SQL连接之间日期计数问题

时间:2019-05-22 09:57:32

标签: sql tsql join

难以解释的问题,请耐心等待。

我有两个表:

1)按日期细分,以及它们是否在当天的“基本”日期(是/否)

ID      Date        Basic_Days
5423    2019-02-03  1
5423    2019-02-04  0
5423    2019-02-05  1
5423    2019-02-06  1
5423    2019-02-07  1
5423    2019-02-08  1
5423    2019-02-09  0
5423    2019-02-10  0
5423    2019-02-11  0
5423    2019-02-12  0
5423    2019-02-13  0
5423    2019-02-14  1
5423    2019-02-15  1
5423    2019-02-16  1

2)按订单细分不同日期的时间段

EPI_Start_Date  EPI_End_Date     ID     EPI_ORDER
2019-02-03      2019-02-04       5423   1
2019-02-04      2019-02-15       5423   2
2019-02-15      2019-02-16       5423   3

我想做的是将各个天数归为各自的EPI_ORDER,但不重复计算天数。

理想的输出是:

Basic_Days  EPI_Start_Date  EPI_End_Date    ID      EPIORDER
1           2019-02-03      2019-02-04      5423    1
5           2019-02-04      2019-02-15      5423    2
2           2019-02-15      2019-02-16      5423    3

到目前为止,我已经尝试过:

我开始的查询几乎使我到达那里。但是我想要一种正确处理最后日期的方法。

SELECT 
 SUM(CAST(p.Basic_Days AS int)) AS Basic_Days
, x.EPI_Start_Date
, x.EPI_End_Date
, p.ID
, x.EPIORDER


FROM *SNIP* AS x

    INNER JOIN *SNIP* table leapfrog join here, unnecessary for display purposes AS cc

    INNER JOIN *SNIP* AS p 
    ON  p.ID = cc.ID

    AND (   (p.[Date] BETWEEN x.EPI_Start_Date AND x.EPI_End_Date) 

        AND (p.[Date] <> x.EPI_End_Date) ) --this was my effort into not counting the last day on each, but it doesn't work for the very final day, where I DO want it.


WHERE p.ID = '5423' --testing

GROUP BY  EPI_Start_Date
        , EPI_End_Date
        , x.EPIORDER
        , ID

我的实际输出给了我

Basic_Days  EPI_Start_Date  EPI_End_Date    ID      EPIORDER
1           2019-02-03      2019-02-04      5423    1
5           2019-02-04      2019-02-15      5423    2
1           2019-02-15      2019-02-16      5423    3

您可以看到最后一行只有1个Basic_Days。但我希望是2个Basic_Days。

我觉得我不太远,但是我只需要调整Join中的AND语句即可。

任何帮助表示赞赏!希望我已经讲得足够好了,可以理解吗?

1 个答案:

答案 0 :(得分:0)

将您的BETWEEN更改为

p.[Date] >= x.EPI_Start_Date AND  p.[Date] < x.EPI_End_Date

BETWEEN在两端都是包容性的,也就是说,它的行为是这样的,它将使您的生活倍增:

--don't want the end date compare to be <=
p.[Date] >= x.EPI_Start_Date AND  p.[Date] <= x.EPI_End_Date

您也可以删除(p.[Date] <> x.EPI_End_Date)

最后,我想指出的是,您的理想输出是不一致的-对于您的大多数理想输出,您都说过您不希望将截止日期的记录包括在该范围内,然后突然想起最后一张唱片,您确实希望它进入乐队。可以设计一个查询来解决这个问题,但这是不一致的数据建模,要有2行在其范围内不包含值,然后一行突然确实包含值,而另一行则不包含“只是因为没有其他范围了”-决定这是否确实是您想要的,因为下次您运行该报告时,“ 15日到16日之间的基本天数”将从2减少到1,因为乐队(例如从16到21)已添加。

诸如此类的事情将错误地将最后一行包含在错误的波段中,“仅仅因为它是最后一行”:

INNER JOIN (SELECT t.*, MAX(EPI_END_DATE) OVER(PARTITION BY ID) as max_end_date FROM date_ranges_table) x
ON 
  p.ID = x.ID AND
  p.[Date] >= x.EPI_Start_Date AND (p.[Date] < x.EPI_End_Date OR p.Date = x.max_end_date)