如何解决将一组 SQL 更改行转换为日期
我有一个表格 (visibility_history
),用于跟踪用户更改其个人资料可见性的日期。我们在首次创建用户个人资料时创建 1 visibility_history
行,并在用户更改其个人资料可见性时创建其他行。
看起来像
user_id | visible_before | visible_after | 日期 |
---|---|---|---|
1 | 无 | 真实 | 2021 年 1 月 1 日 |
1 | 真实 | 假 | 2021 年 1 月 4 日 |
1 | 假 | 真实 | 2021 年 1 月 5 日 |
2 | 无 | 假 | 2021 年 1 月 4 日 |
3 | 无 | 真实 | 2021 年 1 月 4 日 |
在上面的例子中,用户 1 是在 1 月 1 日创建的,用户 2 和 3 是在 1 月 4 日创建的。对于代表用户可见性变化的每一行,我们记录了他们在变化前的个人资料的可见性和更改后。
我想要一个查询,该查询将返回每个用户的个人资料可见的日期集。例如,我会进行查询以返回用户个人资料在 1 月 2 日和 1 月 6 日之间可见的日期。结果将是
user_id | 日期 |
---|---|
1 | 2021 年 1 月 2 日 |
1 | 2021 年 1 月 3 日 |
1 | 2021 年 1 月 5 日 |
1 | 2021 年 1 月 6 日 |
3 | 2021 年 1 月 4 日 |
3 | 2021 年 1 月 5 日 |
3 | 2021 年 1 月 6 日 |
我认为我需要使用计数表,但我不知道在这种情况下如何使用。
解决方法
您需要定义您感兴趣的界限,因为它无法从您想要的 1 月 6 日而不是 1 月 7 日的样本数据中确定。我在我的解决方案中使用了 calendar
CTE,无论如何您可以根据需要对日期常量进行硬编码.
然后,您预先计算每个可见性间隔的上限(包括)(我假设没有带有 visible_before = visible_after
的行),并根据匹配的适当日期范围为每个用户连接具有有效间隔的预生成日期。
with visibility_history (user_id,visible_before,visible_after,date) as (values
(1,null,true,date '2021-01-01'),(1,false,date '2021-01-04'),date '2021-01-05'),(2,(3,date '2021-01-04')
),calendar (min_date,max_date) as (values
(date '2021-01-02',date '2021-01-06')
),precomputed_interval (user_id,since,till) as (
select h.user_id,h.visible_after,h.date,coalesce(lead(h.date) over (partition by h.user_id order by h.date) - interval '1 day',calendar.max_date)
from visibility_history h
cross join calendar
)
select i.user_id,s.d
from generate_series((select min_date from calendar),(select max_date from calendar),'1 day'::interval) as s(d)
join precomputed_interval i on s.d between i.since and i.till
where i.visible_after
order by i.user_id,s.d
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。