难以解释的问题,请耐心等待。
我有两个表:
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语句即可。
任何帮助表示赞赏!希望我已经讲得足够好了,可以理解吗?
答案 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)