Sql 从基于范围的查询中获取所有月份
我有这些数据,我有一个租赁的开始和结束日期。 我需要像下表一样在几个月内拿到它 我尝试使用一个while循环,每个月调用一次作为参数,然后进行计算,但是我得到了许多单独的表,union都不起作用,或者我没有正确地管理它Sql 从基于范围的查询中获取所有月份,sql,sql-server,Sql,Sql Server,我有这些数据,我有一个租赁的开始和结束日期。 我需要像下表一样在几个月内拿到它 我尝试使用一个while循环,每个月调用一次作为参数,然后进行计算,但是我得到了许多单独的表,union都不起作用,或者我没有正确地管理它 对于这项任务,您有好的解决方案吗?我在考虑递归CTE: with cte as ( select name, startrental, endrental, durationdays, (case when eomonth(startrent
对于这项任务,您有好的解决方案吗?我在考虑递归CTE:
with cte as (
select name, startrental, endrental, durationdays,
(case when eomonth(startrental) <= endrental
then day(eomonth(startrental)) - day(startrental) + 1
else day(endrental) - day(startrental) + 1
end) as monthdays
eomonth(startrental) as monthend
from t
union all
select name, startrental, endrental, durationdays,
(case when eomonth(monthend, 1) <= endrental
then day(eomonth(monthend, 1)) - day(startrental) + 1
else day(endrental)
end) as monthdays
eomonth(monthend, 1) as monthend
from cte
where eomonth(monthend) < endrental
)
select *
from cte;
注意:这表示每月最后一天的月份,而不是将年和月放在单独的列中。从发布的信息中可以看出:
SELECT
name,
MIN(startrental) as startrental,
MIN(endrental) as endrental,
DATEDIFF(day, MIN(startrental),
MIN(endrental)) as duration
FROM
table
GROUP BY
name
从下面的表格中,我没有真正理解你的意思——那句话下面没有表格。我假设您的原始数据是源表,较小的顶部表是您试图创建的。我选择这种方式是因为较大的表中的数据不一致,这肯定是人为错误;除非算法非常复杂,并有意构建它们,否则它们不会通过算法生成。如果没有日历表,可以使用特别的理货/数字表 范例 返回 注意:我选择了一个任意日期2000-01-01和10000天的最长日期2027-05-19
此外,我不确定我是否同意您2019年6月的2天期限。它应该是1。如果你解释一下持续时间如何求和的逻辑,可能会有所帮助-为什么c和d一天短?为什么短了两天?您是否忽略了持续时间列并区分了日期?是的,我可能会在计算持续时间时出错。。但这不是这里的主要问题。。。应该是enddate-start date我对这个答案投了赞成票,但您也应该看看日期维度表。它们在很多情况下都很有用,包括这次。@RandySlavey 100%同意。。。一张日历表是值得努力的
Select name
,startRental
,endRental
,durationDays = sum(1)
,month = month(D)
,year = year(D)
From (
Select *
From YourTable A
Join (
Select Top 10000 D=DateAdd(DAY,-1+Row_Number() Over (Order By (Select NULL)),'2000-01-01')
From master..spt_values n1, master..spt_values n2
) B on D between startRental and endRental
) A
Group by Name
,startRental
,endRental
,month(d)
,year(d)
name startRental endRental durationDays month year
a 2019-06-30 2019-07-07 1 6 2019
a 2019-06-30 2019-07-07 7 7 2019
b 2019-03-02 2019-04-03 30 3 2019
b 2019-03-02 2019-04-03 3 4 2019
c 2019-01-01 2019-01-30 30 1 2019
d 2019-01-01 2019-05-01 31 1 2019
d 2019-01-01 2019-05-01 28 2 2019
d 2019-01-01 2019-05-01 31 3 2019
d 2019-01-01 2019-05-01 30 4 2019
d 2019-01-01 2019-05-01 1 5 2019