数据表
假设我们有以下blog
数据表,来存储由我们的平台托管的博客:
而且,我们目前有两个博客:
| id | created_on | title | url |
|----|------------|---------------------|------------------------------------|
| 1 | 2013-09-30 | PostgreSQL Blog | https://www.rockdata.net/blog/ |
| 2 | 2017-01-22 | PostgreSQL Tutorial | https://www.rockdata.net/tutorial/ |
在不使用 LATERAL JOIN 的情况下获取报表
我们需要生成一个报表,用于从blog
表中提取以下数据:
-
博客 ID
-
博客年龄,以年为单位
-
下一次博客周年日的日期
-
距离下一次周年日还剩多少天
使用日期间隔函数计算博客年龄
博客年龄需要通过将当前日期减去博客创建日期来计算。
下一次博客周年日的日期,可以通过将年龄以年为单位递增,并将其添加到博客创建日期来计算。
可以通过从下一次博客周年日和当前日期之间的间隔中提取天数,来计算到下一次周年日的天数。
若要获取结果,可以使用以下查询:
SELECT
b.id as blog_id,
extract(
YEAR FROM age(now(), b.created_on)
) AS age_in_years,
date(
created_on + (
extract(YEAR FROM age(now(), b.created_on)) + 1
) * interval '1 year'
) AS next_anniversary,
date(
created_on + (
extract(YEAR FROM age(now(), b.created_on)) + 1
) * interval '1 year'
) - date(now()) AS days_to_next_anniversary
FROM blog b
ORDER BY blog_id
这样,您将获得预期的结果:
| blog_id | age_in_years | next_anniversary | days_to_next_anniversary |
|---------|--------------|------------------|--------------------------|
| 1 | 7 | 2021-09-30 | 295 |
| 2 | 3 | 2021-01-22 | 44 |
如您所见,age_in_years
必须定义三次,因为在计算next_anniversary
和days_to_next_anniversary
值时需要它。
而这正是 LATERAL JOIN 可以帮助我们的地方。
使用 LATERAL JOIN 获取报表
LATERAL JOIN 允许我们重用age_in_years
值,并在计算next_anniversary
和days_to_next_anniversary
值时进一步传递它。
例如,前面的 SQL 查询可以像这样重写:
SELECT
b.id as blog_id,
age_in_years,
date(
created_on + (age_in_years + 1) * interval '1 year'
) AS next_anniversary,
date(
created_on + (age_in_years + 1) * interval '1 year'
) - date(now()) AS days_to_next_anniversary
FROM blog b
CROSS JOIN LATERAL (
SELECT
cast(
extract(YEAR FROM age(now(), b.created_on)) AS int
) AS age_in_years
) AS t
ORDER BY blog_id
并且,age_in_years
值可以只计算一次,并重用于next_anniversary
和days_to_next_anniversary
的计算:
| blog_id | age_in_years | next_anniversary | days_to_next_anniversary |
|---------|--------------|------------------|--------------------------|
| 1 | 7 | 2021-09-30 | 295 |
| 2 | 3 | 2021-01-22 | 44 |
好多了,对吧?
为blog
表的每条记录计算age_in_years
。这样,它的工作方式类似于相关的子查询,但子查询记录与主表连接,因此,我们可以引用子查询生成的列。
原文始发于微信公众号(红石PG):PostgreSQL LATERAL JOIN 横向连接
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/186476.html