【问题标题】:SQL Between date column filed not nullSQL 之间的日期列字段不为空
【发布时间】:2020-08-11 18:29:24
【问题描述】:

我想统计所有在 2019 年 1 月 1 日活跃的唯一身份客户,条件是他们在接下来的 3 天内也活跃。

主表

date        customer_id   time_spent_online_min
2019-01-01  1             5
2019-01-01  2             6
2019-01-01  3             4
2019-01-02  1             7
2019-01-02  2             5
2019-01-03  3             3
2019-01-04  1             4
2019-01-04  2             6

输出表

date         total_active_customers
2019-01-01   2

这是我迄今为止尝试过的:

with cte as(

select customer_id
      ,date
      ,time_spent_online_min

from main_table
where date between date '2019-01-01' and date '2019-01-04'
and customer_id is not null)

select    date 
         ,count(distinct(customer_id)) as total_active_customers
from cte
where date = date '2019-01-01'
group by 1

【问题讨论】:

    标签: sql presto


    【解决方案1】:

    如果每天只有一条记录,可以使用lead():

    select date, count(*)
    from (select t.*, lead(date, 3) over (partition by customer_id order by date) as date_3
          from main_table t
         ) t
    where date = '2019-01-01' and
          date_3 = '2019-01-04'
    group by date;
    

    如果您每天可以有多个记录,则聚合然后使用lead():

    select date, count(*)
    from (select t.*, lead(date, 3) over (partition by customer_id order by date) as date_3
          from (select customer_id, date, sum(time_spent_online_min) as time_spent_online_min
                from maintable t
                group by customer_id, date
               ) t
         ) t
    where date = '2019-01-01' and
          date_3 = '2019-01-04'
    group by date;
    

    您还可以轻松地将其扩展到任何日期:

    select date, count(*)
    from (select t.*, lead(date, 3) over (partition by customer_id order by date) as date_3
          from main_table t
         ) t
    where date_3 = date + interval '3' day
    group by date;
    

    【讨论】:

      【解决方案2】:

      我会在这里使用存在逻辑:

      SELECT COUNT(*)
      FROM main_table t1
      WHERE
          date = '2019-01-01' AND
          EXISTS (SELECT 1 FROM main_table t2
                  WHERE t2.customer_id = t1.customer_id AND t2.date = '2019-01-02') AND
          EXISTS (SELECT 1 FROM main_table t2
                  WHERE t2.customer_id = t1.customer_id AND t2.date = '2019-01-03') AND        
          EXISTS (SELECT 1 FROM main_table t2
                  WHERE t2.customer_id = t1.customer_id AND t2.date = '2019-01-04');
      

      此答案假定给定客户在一个活动日期只有一条记录。

      【讨论】:

        【解决方案3】:
        WITH
        -- your input
        input(dt,customer_id,time_spent_online_min) AS (
                  SELECT DATE '2019-01-01',1,5
        UNION ALL SELECT DATE '2019-01-01',2,6
        UNION ALL SELECT DATE '2019-01-01',3,4
        UNION ALL SELECT DATE '2019-01-02',1,7
        UNION ALL SELECT DATE '2019-01-02',2,5
        UNION ALL SELECT DATE '2019-01-03',3,3
        UNION ALL SELECT DATE '2019-01-04',1,4
        UNION ALL SELECT DATE '2019-01-04',2,6
        )
        ,
        -- count the active days in this row and the following 3 days
        count_activity AS (
          SELECT
            *
          , COUNT(customer_id) OVER(
              PARTITION BY customer_id ORDER BY dt
              RANGE BETWEEN CURRENT ROW AND INTERVAL '3 DAY'  FOLLOWING
            ) AS act_count
          FROM input
        )
        SELECT
          dt
        , COUNT(*) AS total_active_customers
        FROM count_activity
        WHERE dt='2019-01-01'
          AND act_count > 2
        GROUP BY dt                                                         
        ;
        -- out      dt     | total_active_customers 
        -- out ------------+------------------------
        -- out  2019-01-01 |                      2
        

        【讨论】:

          猜你喜欢
          • 2015-10-01
          • 2023-04-06
          • 2021-12-17
          • 1970-01-01
          • 2018-04-07
          • 1970-01-01
          • 2023-03-14
          • 2021-12-08
          • 1970-01-01
          相关资源
          最近更新 更多