我正在处理一个数据集,该数据集包含用于服务列表的预付款数据。结构为:名称,服务,服务开始(日期),服务终止(日期)。
我需要每年针对每个月报告此数据,回答一个问题:对于给定的服务和月份,预付了多少人?结果将是包容性的,这意味着如果一个名称和服务组合连续一个月达到1天或更长时间,则会对其进行报告。
使用SQL或SQL变体解决此问题的最佳方法是什么?
谢谢!
以下示例输入和输出数据:
IN:
Name,Service,Start,End
jon,a,05/12/2018,08/26/2018
paul,b,06/05/2018,08/08/2018
michael,a,02/18/2018,08/15/2018
mary,a,04/22/2018,10/14/2018
jonas,b,05/10/2018,07/02/2018
thomas,a,08/05/2018,10/18/2018
jessica,c,03/09/2018,07/16/2018
arthur,c,02/03/2018,03/15/2018
hugo,c,06/07/2018,09/01/2018
larry,a,11/23/2018,12/20/2018
nick,b,08/23/2018,11/22/2018
beth,c,09/20/2018,12/25/2018
ashley,a,04/14/2018,05/19/2018
tim,a,01/05/2018,05/26/2018
allan,b,06/28/2018,12/11/2018
jeffrey,b,03/04/2018,04/22/2018
steven,b,01/20/2018,06/07/2018
dawn,c,06/15/2018,10/14/2018
brandy,b,09/01/2018,10/08/2018
christine,a,04/15/2018,07/31/2018
OUT:
Service,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
a,1,2,2,5,6,4,4,4,2,2,1,1
b,1,1,2,2,2,4,3,3,3,3,2,1
c,0,1,2,1,1,3,3,2,3,2,1,1
答案 0 :(得分:0)
您可以尝试使用条件聚合。对于2018年,可能看起来像这样:
SELECT [service],
count(DISTINCT
CASE
WHEN [start] < '2018-02-01'
OR [end] >= '2018-01-01' THEN
[name]
END) [jan],
count(DISTINCT
CASE
WHEN [start] < '2018-03-01'
OR [end] >= '2018-02-01' THEN
[name]
END) [feb],
...
count(DISTINCT
CASE
WHEN [start] < '2019-01-01'
OR [end] >= '2018-12-01' THEN
[name]
END) [dec]
FROM [elbat]
GROUP BY [service];
我假设,您希望有不同的人数(即使一个人出现多次,也只能对一个人计数)。如果不正确,请删除DISTINCT
。
如果服务期刚好与月份重叠,我进一步假设您要计数。如果您只想计算,如果一个月内完全包含了期限,则将条件更改为:
[start] >= <first of month>
AND [end] < <first of next month>
(替换<first of month>
和<first of next month>
。)
顺便说一句,给人们以他们的名字命名是一个坏主意。您是怎么知道一个人或更多,如果还有更多“约翰·史密斯”呢?