我正在从一个网站学习 SQL,他们有 这个问题,我下面的尝试还不够,需要输入。
问题总结:
“找出 2021 年最后一篇帖子和第一篇帖子之间的天数差异。”
数据:
表
posts
:
Column Name Type
user_id integer
post_id integer
post_date timestamp
post_content text
样本数据:
user_id post_id post_date post_content
151652 599415 07/10/2021 12:00:00 Need a hug
661093 624356 07/29/2021 13:00:00 Bed. Class 8-12.
004239 784254 07/04/2021 11:00:00 Happy 4th of July!
661093 442560 07/08/2021 14:00:00 Just going to cry myself to sleep
151652 111766 07/12/2021 19:00:00 I'm so done with covid - need travelling ASAP!
输出示例:
user_id days_between
151652 2
661093 21
我的回答尝试需要大量阅读,而我想出的最好的答案是 PostgreSQL:
WITH
target_year AS
(
SELECT *
FROM
(
SELECT
user_id,
post_date,
dense_rank() over(PARTITION BY user_id order by user_id desc) as n
FROM posts
where EXTRACT('year' from post_date)=2021
order by user_id DESC
) as x
where n <=2
),
target_user AS
(
SELECT user_id,
post_date::date - lag(post_date::date) over (order by user_id) from target_year
)
select * from target_user
order by user_id
我得到的结果是:
user_id column
151325 NULL
151652 -207
151652 244
151652 -307
178425 55
423967 42
661093 105
661093 21
661093 -206
我对以上内容感到困惑
我在
where n <=2
子句with
中选择了target_year
。我预计每组最多只有两个结果,但上面显示至少有三个结果。我的逻辑怎么被打破了?
我的理解是,通过使用类型
::date
,它会将日期强制转换为天。如何使日期成为绝对日期,以及为什么它们是负数?我对逻辑的理解是,因为我按日期降序排列,前两个结果应该只从较小的数字 (lag(post_date::date)) 中减去较大的数字 (post_date::date
),因此负数的存在应该不可能,我的逻辑怎么错了?
此外,当我将
where n <=2
子句 where n >=2
中的逻辑从 with
更改为 target_year
时。我没有得到任何结果。我预计至少有两到三个条目的人会在那里。为什么这个逻辑不起作用?
可以在单个查询级别中使用普通聚合来完成:
SELECT user_id
, max(post_date)::date - min(post_date)::date AS days_between
FROM posts
WHERE post_date >= '2021-01-01'
AND post_date < '2022-01-01'
GROUP BY user_id
HAVING count(*) > 1
ORDER BY user_id;