Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 从基于范围的查询中获取所有月份_Sql_Sql Server - Fatal编程技术网

Sql 从基于范围的查询中获取所有月份

Sql 从基于范围的查询中获取所有月份,sql,sql-server,Sql,Sql Server,我有这些数据,我有一个租赁的开始和结束日期。 我需要像下表一样在几个月内拿到它 我尝试使用一个while循环,每个月调用一次作为参数,然后进行计算,但是我得到了许多单独的表,union都不起作用,或者我没有正确地管理它 对于这项任务,您有好的解决方案吗?我在考虑递归CTE: with cte as ( select name, startrental, endrental, durationdays, (case when eomonth(startrent

我有这些数据,我有一个租赁的开始和结束日期。 我需要像下表一样在几个月内拿到它

我尝试使用一个while循环,每个月调用一次作为参数,然后进行计算,但是我得到了许多单独的表,union都不起作用,或者我没有正确地管理它


对于这项任务,您有好的解决方案吗?

我在考虑递归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