所以我需要计算用户的连续记录(他创建条目的连续天数)。目前,我进行了一个对条目进行分组的查询,它给了我最后一组条纹。这是架构的一部分(postgres):
CREATE TABLE "diaries" (
"id" SERIAL NOT NULL,
"text" VARCHAR(4000),
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"user_profile_id" INTEGER NOT NULL,
CONSTRAINT "diaries_pkey" PRIMARY KEY ("id"));
这是查询
WITH daily_entries AS (
SELECT
user_profile_id,
created_at::date AS entry_date
FROM
diaries
WHERE
user_profile_id = 1
AND created_at::date <= CURRENT_DATE
GROUP BY
user_profile_id, created_at::date
),
streaks AS (
SELECT
user_profile_id,
entry_date,
entry_date - INTERVAL '1 day' * ROW_NUMBER() OVER (PARTITION BY user_profile_id ORDER BY entry_date) AS streak_group
FROM
daily_entries
),
streaks_summary AS (
SELECT
user_profile_id,
MIN(entry_date) AS streak_start,
MAX(entry_date) AS streak_end,
COUNT(*) AS streak_length
FROM
streaks
GROUP BY
user_profile_id, streak_group
)
SELECT
streak_length
FROM
streaks_summary
WHERE
streak_end = CURRENT_DATE
AND (user_profile_id = 1);
我正在寻找一种优化扩展的方法。我正在考虑在创建时计算的每个条目中添加一个字段“条纹”,这样就不需要重新计算整个表的条纹,但我不确定这个解决方案。还有其他现有的方法吗?
您可以考虑间隙和孤岛类型任务的常用解决方案。
它是否会比你提出的更好是一个有趣的问题。
示例
select user_profile_id,min(created_at) start_from,max(created_at) end_to,count(*) cnt
,count(distinct created_at::date)qd
from(
select *
,sum(new_streak)over(PARTITION BY user_profile_id ORDER BY created_at) grn
from(
select *
,case when
lag(created_at,1,created_at)OVER(PARTITION BY user_profile_id ORDER BY created_at)::date
>= created_at::date - INTERVAL '1 day'
then 0
else 1
end new_streak
from diaries
where (user_profile_id = 1)
AND created_at::date <= CURRENT_DATE
)t
)
group by user_profile_id,grn
having max(created_at)::date=current_date
一些优化 - 获取最后一组行
select user_profile_id,min(created_at) start_from,max(created_at) end_to,count(*) cnt
,count(distinct created_at::date)qd
from(
select *
,sum(new_streak)over(PARTITION BY user_profile_id ORDER BY created_at desc) grn
from(
select *
,case when
lag(created_at,1,created_at)
OVER(PARTITION BY user_profile_id ORDER BY created_at desc)::date
<= created_at::date + INTERVAL '1 day'
then 0
else 1
end new_streak
from diaries
where (user_profile_id = 1)
AND created_at::date <= CURRENT_DATE
)t
)
where grn=0
group by user_profile_id
用户个人资料_id | 开始于 | 结束 | cnt | qd |
---|---|---|---|---|
1 | 2024-06-16 19:00:00 | 2024-06-18 21:00:00 | 6 | 3 |
我们按照
desc
的顺序分组,并选择第一组。
id | 文字 | 创建于 | 用户个人资料_id | 新条纹 | grn |
---|---|---|---|---|---|
15 | 文字1-2 | 2024-06-18 21:00:00 | 1 | 0 | 0 |
14 | 文字1-2 | 2024-06-17 18:59:00 | 1 | 0 | 0 |
13 | 文字1-2 | 2024-06-16 22:00:00 | 1 | 0 | 0 |
12 | 文字1-2 | 2024-06-16 21:00:00 | 1 | 0 | 0 |
11 | 文字1-2 | 2024-06-16 20:00:00 | 1 | 0 | 0 |
10 | 文字1-2 | 2024-06-16 19:00:00 | 1 | 0 | 0 |
9 | 文字1-2 | 2024-06-09 20:00:00 | 1 | 1 | 1 |
8 | 文字1-2 | 2024-06-08 19:00:00 | 1 | 0 | 1 |
7 | 文字1-2 | 2024-06-06 19:00:00 | 1 | 1 | 2 |
6 | 文字1-2 | 2024-06-05 19:00:00 | 1 | 0 | 2 |
5 | 文字1-2 | 2024-06-04 19:00:00 | 1 | 0 | 2 |
4 | 文字1-2 | 2024-06-03 19:00:00 | 1 | 0 | 2 |
3 | 文字1-2 | 2024-06-02 19:00:00 | 1 | 0 | 2 |
2 | 文字1-2 | 2024-06-02 19:00:00 | 1 | 0 | 2 |
1 | 文本1-1 | 2024-06-01 19:00:00 | 1 | 0 | 2 |