一份查询说明说“子查询要用前面那张表当前行的值”,还没有交代子查询位于哪里。如果它是FROM列表中的一项,PostgreSQL 17第7.2.1.5节用LATERAL明确表达这种关系:该子查询可以引用前面的FROM项提供的列。[1] 关键不是给子查询多起一个名字,而是允许它与前面的来源行发生横向联系。
文档先给出不带LATERAL时的对照:FROM中的各子查询独立求值,不能交叉引用其他FROM项。这里限定的是这一位置的子查询,不能扩大成SQL中所有位置的子查询都禁止引用外层列。读资料时保留FROM这个范围,才能知道该关键字正在解决哪一种引用问题。
随后给出的求值关系更具体。对提供被引用列的每一行,或由多个来源项形成的一组行,LATERAL项使用这些列值求值;所得到的行再与它们的来源行按通常方式连接。这个过程对各来源行重复。于是,不能把它简单画成一个与来源行无关、只算一次的固定结果表。
官方用多边形顶点函数说明用途:函数需要某个多边形作为参数,再返回该多边形的顶点集合。不同来源行所提供的多边形,可以成为各自求值的输入。本文采用这个对象关系帮助解释逐行绑定,没有执行示例中的查询、比较距离或生成几何数据,也没有把文档例子当成性能测试。
表函数还带着一个重要例外。文档明确说,FROM中的表函数参数本来就能引用前面项的列,因此LATERAL关键字在函数情形是可选的;示例中保留它是为了让关系更清楚。不能先读到子查询需要这个关键字,再推断凡是没写该词的函数都不能使用前面行的参数。子查询与表函数应按原文各自的规则解释。
连接方式决定另一项结果含义。该节说明,LEFT JOIN到LATERAL子查询时,即使子查询没有为某个来源行产生结果,该来源行仍能出现在连接结果中。厂商与产品名的教学例就是为展示这一点:某厂商没有产品结果,不必因此在左连接结果中消失。这里说明的是左连接条件下的保留关系,不把它概括成所有LATERAL用法都保留全部来源行。
LATERAL也可以出现在JOIN树中;当它位于某个JOIN的右侧,可以引用该JOIN左侧的项。把引用来源、逐行输入和连接方式分别说明,就能读清查询正在组合什么。本文固定采用PostgreSQL 17文档,不提供生产SQL改写或速度结论;网页导航中的新闻日期不被当作本节的首次发布日期。
信息来源
本文基于上述公开资料整理,未使用来源页面的图片、视频或嵌入媒体。