och*_*hii 4 postgresql postgresql-9.6
首先,我是这个论坛的新手。我希望有人能就我的问题提供帮助或建议。
给定用户 createdAt 日期和当前日期。我想在这些日期之间以 10 个线性时间间隔检索用户的 Friends 记录总和。
因此,如果 createdAt 是 30 天前,那么我想要每隔 3 天间隔的用户好友总数。
用户表
??????????????????????????????????????????????
? id ? name ? createdAt ?
??????????????????????????????????????????????
? 1 ? Timothee ? 2018-03-01 13:02:20.904+00 ?
??????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
朋友桌
???????????????????????????????????????????????????????
? id ? userId ? friendId ? createdAt ?
???????????????????????????????????????????????????????
? 1 ? 1 ? 234 ? 2018-03-20 15:41:51.779+00 ?
???????????????????????????????????????????????????????
? 2 ? 1 ? 254 ? 2018-03-20 16:16:34.698+00 ?
???????????????????????????????????????????????????????
? 3 ? 1 ? 288 ? 2018-03-15 15:17:39.907+00 ?
???????????????????????????????????????????????????????
? 4 ? 1 ? 293 ? 2018-03-07 16:15:49.379+00 ?
???????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
预期产出
?????????????????????????????????????????????????????????????????????
? ? count ? startDate ? endDate ?
?????????????????????????????????????????????????????????????????????
? ? 0 ? 2018-03-01 13:02:20.904+00 ? 2018-03-03 13:02:20.904+00 ?
?????????????????????????????????????????????????????????????????????
? ? 0 ? 2018-03-03 13:02:20.904+00 ? 2018-03-05 13:02:20.904+00 ?
?????????????????????????????????????????????????????????????????????
? ? 0 ? 2018-03-05 13:02:20.904+00 ? 2018-03-07 13:02:20.904+00 ?
?????????????????????????????????????????????????????????????????????
? ? 1 ? 2018-03-07 13:02:20.904+00 ? 2018-03-09 13:02:20.904+00 ?
?????????????????????????????????????????????????????????????????????
? ? 1 ? 2018-03-09 13:02:20.904+00 ? 2018-03-11 13:02:20.904+00 ?
?????????????????????????????????????????????????????????????????????
? ? 1 ? 2018-03-11 13:02:20.904+00 ? 2018-03-13 13:02:20.904+00 ?
?????????????????????????????????????????????????????????????????????
? ? 1 ? 2018-03-13 13:02:20.904+00 ? 2018-03-15 13:02:20.904+00 ?
?????????????????????????????????????????????????????????????????????
? ? 2 ? 2018-03-15 13:02:20.904+00 ? 2018-03-17 13:02:20.904+00 ?
?????????????????????????????????????????????????????????????????????
? ? 2 ? 2018-03-17 13:02:20.904+00 ? 2018-03-19 13:02:20.904+00 ?
?????????????????????????????????????????????????????????????????????
? ? 4 ? 2018-03-19 13:02:20.904+00 ? 2018-03-21 13:02:20.904+00 ?
?????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
我可以使用以下 SQL-Server 查询获得所需的天数间隔:
@DECLARE @EndDate DATE = GETDATE();
WITH start as
(SELECT createdAt
FROM user where id = '123'
)
SELECT diff/10
FROM (
SELECT DATEDIFF(days, start, @EndDate)
) as diff
Run Code Online (Sandbox Code Playgroud)
这在 PostgreSQL 中会怎样?
我也知道我可以使用 SQL-Server 查询检索静态日期范围之间的记录数:
SELECT count(*)
FROM friends
WHERE userId = '123'
AND date BETWEEN CURDATE() - INTERVAL 3 DAY AND CURDATE()
Run Code Online (Sandbox Code Playgroud)
这在 PostgreSQL 中会怎样?
但我正在努力解决的是这两件事的结合。
如何检索两个日期之间所有日期间隔内的记录总和?
我希望这个问题是可以理解的,感谢您的任何帮助或建议。
Postgres 允许使用 generate_series() 函数生成一系列日期。
select generate_series(createdAt, current_date,
(date_part('day', current_date::timestamp - createdAt::timestamp) / 10)::int * '1 day'::interval) ddate
, (date_part('day', current_date::timestamp - createdAt::timestamp) / 10)::int * '1 day'::interval as ddays
from users
where id = 1;
Run Code Online (Sandbox Code Playgroud)
它返回:
日期 | 天 :-------------- | :----- 2018-03-01 13:02:20.904 | 2天 2018-03-03 13:02:20.904 | 2天 2018-03-05 13:02:20.904 | 2天 2018-03-07 13:02:20.904 | 2天 2018-03-09 13:02:20.904 | 2天 2018-03-11 13:02:20.904 | 2天 2018-03-13 13:02:20.904 | 2天 2018-03-15 13:02:20.904 | 2天 2018-03-17 13:02:20.904 | 2天 2018-03-19 13:02:20.904 | 2天
然后您可以使用先前的查询来计算此间隔之间的朋友数:
with x as
(
select generate_series(createdAt, current_date,
(date_part('day', current_date::timestamp - createdAt::timestamp) / 10)::int * '1 day'::interval) ddate
, (date_part('day', current_date::timestamp - createdAt::timestamp) / 10)::int * '1 day'::interval as ddays
from users
where id = 1
)
select ddate,
(select count(*)
from friends
where createdAt >= ddate
and createdAt < ddate + ddays) friends
from x;
Run Code Online (Sandbox Code Playgroud)
最后结果:
日期 | 朋友们 :-------------- | ------: 2018-03-01 13:02:20.904 | 0 2018-03-03 13:02:20.904 | 0 2018-03-05 13:02:20.904 | 0 2018-03-07 13:02:20.904 | 1 2018-03-09 13:02:20.904 | 0 2018-03-11 13:02:20.904 | 0 2018-03-13 13:02:20.904 | 0 2018-03-15 13:02:20.904 | 1 2018-03-17 13:02:20.904 | 0 2018-03-19 13:02:20.904 | 2
或者,如果您更喜欢连接而不是相关的标量子查询:
with x as
(
select generate_series(createdAt, current_date,
(date_part('day', current_date::timestamp - createdAt::timestamp) / 10)::int * '1 day'::interval) ddate
, (date_part('day', current_date::timestamp - createdAt::timestamp) / 10)::int * '1 day'::interval as ddays
from users
where id = 1
)
select ddate,
count(friends.*) as friends
from x
left join friends
on createdAt >= ddate
and createdAt < ddate + ddays
group by ddate
order by ddate;
Run Code Online (Sandbox Code Playgroud)
根据您的预期输出,可以进一步修改最后一个选项以返回运行总计:
with x as
(
select generate_series(createdAt, current_date,
(date_part('day', current_date::timestamp - createdAt::timestamp) / 10)::int * '1 day'::interval) ddate
, (date_part('day', current_date::timestamp - createdAt::timestamp) / 10)::int * '1 day'::interval as ddays
from users
where id = 1
)
select ddate,
count(friends.*) as friends,
sum(count(friends.*)) over (order by ddate) as friends_total
from x
left join friends
on createdAt >= ddate
and createdAt < ddate + ddays
group by ddate
order by ddate;
Run Code Online (Sandbox Code Playgroud)
结果:
日期 | 朋友 | 朋友总数 :-------------- | ------: | ------------: 2018-03-01 13:02:20.904 | 0 | 0 2018-03-03 13:02:20.904 | 0 | 0 2018-03-05 13:02:20.904 | 0 | 0 2018-03-07 13:02:20.904 | 1 | 1 2018-03-09 13:02:20.904 | 0 | 1 2018-03-11 13:02:20.904 | 0 | 1 2018-03-13 13:02:20.904 | 0 | 1 2018-03-15 13:02:20.904 | 1 | 2 2018-03-17 13:02:20.904 | 0 | 2 2018-03-19 13:02:20.904 | 2 | 4
dbfiddle在这里
归档时间: |
|
查看次数: |
6963 次 |
最近记录: |