SQL 查询根据日期获取最新的 3 次发送,然后对记录进行分组

Posted

技术标签:

【中文标题】SQL 查询根据日期获取最新的 3 次发送,然后对记录进行分组【英文标题】:SQL query to fetch latest 3 sends based on date and then group the records 【发布时间】: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 请分享创建表和插入脚本。 【参考方案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

以上是关于SQL 查询根据日期获取最新的 3 次发送,然后对记录进行分组的主要内容,如果未能解决你的问题,请参考以下文章

SQL 查询以获取特定对象的最新操作/更新

SQL - 按电子邮件和最新日期分组

如何查询 sql 以获取最新的记录日期,但如果记录有消息返回该 reocrd [关闭]

SQL查询获取特定日期和列中最新日期之间的数据

查找 sql 查询以获取每个分组的最新关联日期

sql查询获取每个id的最新记录