在 SQL 中筛选上下文和分组依据

Filter Context and Group by in SQL

考虑具有 2 列的 table,每次用户登录时都会有一个新行。(大约 1000 万行并且可能有重复,因为用户每月可以登录多次)

Sign in Month MemberID
2020-10 1000000
2020-12 1000001

现在要找出每个月的唯一用户,我可以使用以下查询。

Select Sign_in_Month, count(distinct(memberid)) as unique_users from table group by Sign_in_Month

但我想将第一个查询中的非重复计数进一步分为 2 个群组,其中用户要么在过去 3 个月之前登录,要么没有登录。 (2020 年 10 月为 2020 年 7 月至 9 月,2020 年 9 月为 2020 年 6 月至 8 月

我曾经通过 DAX 在 powerBI 中执行此操作,这在过滤器上下文中很容易,但我不确定如何在 SQL 中实现此操作。

想要结果

Sign in Month Total Unique Users Unique Users who signed in in the last 3 months Unique Users who did not sign in in the last 3 months
2020-10 4000 3000 1000
2020-11 5000 2500 2500
2020-12 3500 1500 2000

最后 2 列加起来应该是第二列。

我如何创建某种指标来指示会员在过去 3 个月内在哪里购物参考那个特定月份?

谢谢

你可以试试下面的脚本-

注意:语法是针对MSSQL的,逻辑是全局的

select 
sign_in_month,
count(distinct MemberId) as total_unique_user,
count(
    CASE 
        WHEN CAST(sign_in_month+'-01' as Date) >= DATEADD(mm,-4,getdate()) then MemberId
        else null
    end
) as last_3_month,
count(
    CASE 
        WHEN CAST(sign_in_month+'-01' as Date) < DATEADD(mm,-4,getdate()) then MemberId
        else null
    end
) as before_3_month

from your_table_name
GROUP BY sign_in_month

我会按如下方式处理:

  • 每月获得一个唯一值。
  • 使用lag()查看上个月有人登录。
  • 比较时差

为方便起见,我会将 sign_in_month 转换为日期:

select sign_in_date,
       count(*) as num_members,
       sum(case when prev_sign_in_date >= dateadd(month, -4, sign_in_date)
                then 1 else 0 
           end) as num_members_who_signed_in
from (select t.memberId, v.sign_in_date,
             lag(v.sign_in_date) over (partition by t.memberId order by v.sign_in_date) as prev_sign_in_date
      from t cross apply
           (values (convert(date, t.sign_in_month, '-01'))
           ) v(sign_in_date)
      group by t.memberId, v.sign_in_date
     ) t
group by sign_in_date;

请注意,不再需要 count(distinct),因为子查询会处理它。