【问题标题】:SQL query to fetch latest 3 sends based on date and then group the recordsSQL 查询根据日期获取最新的 3 次发送,然后对记录进行分组
【发布时间】:2021-06-30 08:43:20
【问题描述】:

我有一个表格,每个产品 id(pid) 都有电子邮件 sent_dateclick_date,如下例所示:

email pid sent_date click_date
A@gmail.com 1001 1 May 2021 21:12 null
A@gmail.com 1001 2 May 2021 21:12 null
A@gmail.com 1001 3 May 2021 21:12 3 May 2021 21:12
B@gmail.com 1001 1 May 2021 21:12 1 May 2021 21:12
B@gmail.com 1001 2 May 2021 21:12 2 May 2021 21:12
B@gmail.com 1001 3 May 2021 21:12 3 May 2021 21:12
A@gmail.com 1007 1 May 2021 21:12 1 May 2021 21:12
A@gmail.com 1007 2 May 2021 21:12 null
A@gmail.com 1007 3 May 2021 21:12 3 May 2021 21:12
A@gmail.com 1007 4 May 2021 21:12 null
A@gmail.com 1007 5 May 2021 21:12 null
A@gmail.com 1007 6 May 2021 21:12 null

在这个表中,我需要建立一个名为“Last 3 sent_clickCount”的新表。

所以决赛桌应该如下所示:

email pid. clickCount
A@gmail.com 1001 1
B@gmail.com 1001 3
A@gmail.com 1007 null

我想根据pid 考虑仅对最近 3 次发送的点击。

【问题讨论】:

  • 我删除了冲突的 DBMS 标签。请为您真正使用的数据库产品添加一个标签。
  • @sfmc_newbie 请分享创建表和插入脚本。

标签: sql


【解决方案1】:
select t1.email,
       t1.pid,
       count(case when rn <= 3 then t1.click_date else null end) clickcount
  from (
select t1.email,
       t1.pid,
       row_number() over(partition by t1.email, t1.pid order by t1.sent_date desc) rn,
       t1.click_date
  from tab1 t1 
) t1
 group by t1.email,
       t1.pid
;

【讨论】:

    【解决方案2】:

    像下面这样的查询可以解决问题

    with cte as (
    SELECT *
    ,RANK() over (partition by email,pid order by sent_date desc) as ranking
    FROM #temp
    )
    select email,pid
    ,sum(case when click_date is null then null else 1 end) clickcount
    from cte
    where ranking <=3
    group by email,pid
    

    【讨论】:

      【解决方案3】:

      你可以试试这个:

      CREATE TABLE #temp 
      (  email varchar(20)
        ,pid    int
        ,sent_date datetime
        ,click_date datetime
      ) 
      
      INSERT INTO #temp VALUES 
      ('A@gmail.com',1001,'1 May 2021 21:12',null)
      ,('A@gmail.com',1001,'2 May 2021 21:12',null)
      ,('A@gmail.com',1001,'3 May 2021 21:12','3 May 2021 21:12')
      ,('B@gmail.com',1001,'1 May 2021 21:12','1 May 2021 21:12')
      ,('B@gmail.com',1001,'2 May 2021 21:12','2 May 2021 21:12')
      ,('B@gmail.com',1001,'3 May 2021 21:12','3 May 2021 21:12')
      ,('A@gmail.com',1007,'1 May 2021 21:12','1 May 2021 21:12')
      ,('A@gmail.com',1007,'2 May 2021 21:12',null)
      ,('A@gmail.com',1007,'3 May 2021 21:12','3 May 2021 21:12')
      ,('A@gmail.com',1007,'4 May 2021 21:12',null)
      ,('A@gmail.com',1007,'5 May 2021 21:12',null)
      ,('A@gmail.com',1007,'6 May 2021 21:12',null)
      
      
      SELECT email,
             pid,
             clickCount
      FROM
      (
             SELECT *
                    ,RANK() over (partition by email,pid order by sent_date desc) as ranking
             FROM #temp
      ) as ranktable
      OUTER APPLY (SELECT CASE WHEN ranktable.click_date IS NOT NULL 
                               THEN COUNT(*) 
                          ELSE 
                                    NULL
                          END AS clickCount 
                    FROM #temp AS t 
                    WHERE t.pid = ranktable.pid 
                    AND t.email = ranktable.email 
                    AND click_date IS NOT NULL
                  ) as counttable
      WHERE ranking = 1
      
      drop table #temp
      

      上面提到的编码应该在MSSQL上使用(SQL Server 2005以上)

      首先,使用rank找出最新的3个sent_date。

      其次,使用outer apply 查找点击次数。如果最新的click_date是null,则返回null,否则返回clickCount

      【讨论】:

      • outer apply 是非标准 SQL(与 #temp 一样) - 请提及对其有效的 DBMS
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-21
      • 2021-12-05
      • 1970-01-01
      • 2017-10-02
      • 1970-01-01
      • 1970-01-01
      • 2022-01-06
      相关资源
      最近更新 更多