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_date
和 click_date
,如下例所示:
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”的新表。
所以决赛桌应该如下所示:
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 次发送,然后对记录进行分组的主要内容,如果未能解决你的问题,请参考以下文章