具有日期范围的数据,需要按月逐年报告

时间:2018-08-30 23:02:51

标签: sql aggregate

我正在处理一个数据集,该数据集包含用于服务列表的预付款数据。结构为:名称,服务,服务开始(日期),服务终止(日期)。

我需要每年针对每个月报告此数据,回答一个问题:对于给定的服务和月份,预付了多少人?结果将是包容性的,这意味着如果一个名称和服务组合连续一个月达到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

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>。)

顺便说一句,给人们以他们的名字命名是一个坏主意。您是怎么知道一个人或更多,如果还有更多“约翰·史密斯”呢?