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

Posted

技术标签:

【中文标题】请求有关如何在一个查询中对多个条件的计数进行分组的帮助【英文标题】:Requesting help on how to group the counts of multiple conditions in one query 【发布时间】:2019-09-18 13:39:05 【问题描述】:

我需要计算在给定时间范围内生效日期早于月份结束日期并且终止日期在第一个日期月份之前的订阅者数量。然后,我需要将这些结果分组到按年和月格式化的报告中。如果订阅者在 2019 年 2 月 12 日成为订阅者并且在 2019 年 10 月 12 日之前一直是订阅者,则输出需要反映订阅者有效的每个月的计数为 1,而订阅的计数为 0没有效果。我需要计算满足每个条件的位置,而不仅仅是像 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, Character, 20, 20 Eff_Date, 日期, 8, DATETIME22.3 Term_Date, 日期, 8, DATETIME22.3

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

非常感谢任何帮助。

【问题讨论】:

【参考方案1】:
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) 的表并将该日期添加 1 个月 (date2)。

【讨论】:

嗨@Stats_Help_Wanted。感谢您分享该解决方案。不幸的是,它没有在结果集中产生任何东西。我在结果集中有一行值为“。” Year_Month 列中的值和subscriber_count 列中的空值。我确实遵循您的逻辑,但是无论是使用生成的 date_months DATA 步骤还是创建日历表,我都无法使用此解决方案生成所需的输出。我创建了一个日历表,但 SAS 处理日期的方式令人沮丧。但是,这并没有阻止我在使用基于日期的逻辑时能够进行计数或求和。

以上是关于请求有关如何在一个查询中对多个条件的计数进行分组的帮助的主要内容,如果未能解决你的问题,请参考以下文章

如何在单个 SQL 查询中使用多个计数和按条件分组

根据 3 到 4 个条件对数据库表中的行进行计数和分组查询

在sql中组合多个计数查询

如何在 Prometheus 查询中对标签进行分组?

在 Master 中对记录进行分组,但希望对 Details 进行计数

如何在 Promscale 的聚合查询中对标签进行分组