请求有关如何在一个查询中对多个条件的计数进行分组的帮助

时间:2019-04-29 22:38:31

标签: sql ansi-sql ansi-sql-92

我需要计算在给定时间范围内生效日期早于月份结束日期且终止日期早于第一个月的订户数量。然后,我需要将这些结果分组为按年和月格式化的报告。如果订阅者在2019年2月12日成为订阅者,并且在2019年12月10日之前是订阅者,则输出需要反映该订阅者本应有效的每个月的计数为1,在订阅的计数为零没有效果。我需要计算满足每个条件的位置,而不仅仅是像CASE那样满足第一个条件的位置。

我使用SAS并尝试使用CASE WHEN手动创建年月分组,以用于汇总满足每个WHEN条件的订户。我怀疑随着第一个条件的满足,CASE终止,这将无法实现我希望的目标,从而消除了本练习的重点。我需要计算订户有效的每个year_month期间。使用CASE时,由于CASE的工作原理,仅计算有效订阅的第一个月,其余订阅期限从计数中删除。

    create table subscriber_testing as
        select distinct
            case    
                when    sub_eff_date < '01Feb2018'd and sub_term_date >= '01Jan2018'd then '201801'
                when    sub_eff_date < '01Mar2018'd and sub_term_date >= '01Feb2018'd then '201802'
                when    sub_eff_date < '01Apr2018'd and sub_term_date >= '01Mar2018'd then '201803'
                when    sub_eff_date < '01May2018'd and sub_term_date >= '01Apr2018'd then '201804'
                when    sub_eff_date < '01Jun2018'd and sub_term_date >= '01May2018'd then '201805'
                when    sub_eff_date < '01Jul2018'd and sub_term_date >= '01Jun2018'd then '201806'
                when    sub_eff_date < '01Aug2018'd and sub_term_date >= '01Jul2018'd then '201807'
                when    sub_eff_date < '01Sep2018'd and sub_term_date >= '01Aug2018'd then '201808'
                when    sub_eff_date < '01Oct2018'd and sub_term_date >= '01Sep2018'd then '201809'
                when    sub_eff_date < '01Nov2018'd and sub_term_date >= '01Oct2018'd then '201810'
                when    sub_eff_date < '01Dec2018'd and sub_term_date >= '01Nov2018'd then '201811'
                when    sub_eff_date < '01Jan2019'd and sub_term_date >= '01Dec2018'd then '201812'
                when    sub_eff_date < '01Feb2019'd and sub_term_date >= '01Jan2019'd then '201901'
                when    sub_eff_date < '01Mar2019'd and sub_term_date >= '01Feb2019'd then '201902'
                when    sub_eff_date < '01Apr2019'd and sub_term_date >= '01Mar2019'd then '201903'
                else "n/a"
            end 
        as year_month,
            count(distinct subscriber_ID) as subscriber_count
        from
            prod.subscriber_detail      where
            subscriber_group like '%product_tx_%'
            and
            sub_term_date >= '01jan2018'd
            and
            sub_eff_date <= '31mar2019'd
;
quit;

如果我要查询一个订户,则结果应产生此所需的输出:


——————————————————————————
column1_year_month
201801
201802
201803
201804
201805
201806
201807
201808
201809
201810
201811
201812


column2_subscriber_count
0
1
1
1
1
1
1
1
1
0
0
——————————————————————————

从结果集中可以看到,在没有订阅者的月份中,我还需要报告零。

数据列存储在一个表中,如下所示:
名称,类型,长度,格式
产品,字符,80、80
Subscriber_ID,字符,20、20
Eff_Date,日期,8,DATETIME22.3
Term_Date,日期,8月,DATETIME22.3

Excel中的COUNTIF函数可以很好地解决此问题,但是我还没有找到一种在DBMS中严格完成此任务的方法。我希望找到一个与DBMS无关的解决方案。不幸的是,一旦满足条件,CASE表达式将终止。我需要的是对满足的每个条件进行计数的工具,它使我可以按它们匹配的每月期限对这些计数进行分组。

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

data date_months;
infile cards dlm=',' dsd;
input date1 :DATE9. date2 :DATE9.;
cards;
01Jan2018,01Feb2018
01Feb2018,01Mar2018
01Mar2018,01Apr2018
01Apr2018,01May2018
01May2018,01Jun2018
01Jun2018,01Jul2018
01Jul2018,01Aug2018
01Aug2018,01Sep2018
01Sep2018,01Oct2018
01Oct2018,01Nov2018
01Nov2018,01Dec2018
01Dec2018,01Jan2019
01Jan2019,01Feb2019
01Feb2019,01Mar2019
01Mar2019,01Apr2019
01Apr2019,01May2019
;
RUN;

PROC SQL;
create table subscriber_testing as
        select distinct
             a.Date1 as Year_Month,
            count(distinct subscriber_ID) as subscriber_count
        from
                date_months a
                left join prod.subscriber_detail b ON b.sub_eff_date < a.Date2 AND b.sub_term_date >= a.Date1
        where
            subscriber_group like '%product_tx_%'
            and
            sub_term_date >= '01jan2018'd
            and
            sub_eff_date <= '31mar2019'd
;
quit;

免责声明:自从我使用SAS已有很长时间了。

如果数据库中有一个便捷的日历表,则可以创建一个月的第一天(date1)的表,并向该日期(date2)添加1个月。