PostgreSQL LATERAL JOIN 横向连接

数据表

假设我们有以下blog数据表,来存储由我们的平台托管的博客:

PostgreSQL LATERAL JOIN 横向连接

而且,我们目前有两个博客:

| 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_anniversarydays_to_next_anniversary值时需要它。

而这正是 LATERAL JOIN 可以帮助我们的地方。

使用 LATERAL JOIN 获取报表

LATERAL JOIN 允许我们重用age_in_years值,并在计算next_anniversarydays_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_anniversarydays_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

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!