在FROM中出现的子查询前面可以加上关键字LATERAL。这允许它们引用前面FROM项提供的并列列。(如果没有LATERAL,每个子查询都是独立求值的,因此不能交叉引用任何其他FROM项。)

出现在FROM中的表函数前也可以加上关键字LATERAL,但对于函数,关键字是可选的;函数的参数在任何情况下都可以包含对前面FROM项提供的列的引用。

LATERAL项可以出现在FROM列表的顶层,也可以出现在JOIN树中。在后一种情况下,它还可以引用位于JOIN的右侧的左侧的任何项。

当FROM项包含横向交叉引用时,计算过程如下:对于提供交叉引用的列的FROM项的每一行,或提供列的多个FROM项的行集,使用该行或行集的列值计算横向项。结果行通常与计算它们的行连接。对于列源表中的每一行或每一组行重复此操作。

一个简单的LATERAL例子是:

SELECT * FROM foo, LATERAL (SELECT * FROM bar WHERE bar.id =
 foo.bar_id) ss;

这并不是特别有用,因为它与更常规的结果完全相同

SELECT * FROM foo, bar WHERE bar.id = foo.bar_id;

当需要交叉引用列来计算要连接的行时,LATERAL主要有用。一个常见的应用程序正在为集返回函数提供参数值。例如,假设vertices(polygon)返回一个多边形的顶点集合,我们可以用以下方法识别存储在表中的多边形的紧密顶点:

SELECT p1.id, p2.id, v1, v2
FROM polygons p1, polygons p2,
 LATERAL vertices(p1.poly) v1,
 LATERAL vertices(p2.poly) v2
WHERE (v1 <-> v2) < 10 AND p1.id != p2.id;

也可以编写此查询

SELECT p1.id, p2.id, v1, v2
FROM polygons p1 CROSS JOIN LATERAL vertices(p1.poly) v1,
 polygons p2 CROSS JOIN LATERAL vertices(p2.poly) v2
WHERE (v1 <-> v2) < 10 AND p1.id != p2.id;

或者在其他一些等价的公式中。(如前所述,LATERAL关键字在本例中是不必要的,但为了清晰起见,我们使用它。)

LEFT JOIN到LATERAL子查询通常特别方便,这样即使LATERAL子查询没有为源行生成行,源行也会出现在结果中。例如,如果get_product_names()返回制造商生产的产品的名称,但我们表中的一些制造商目前没有生产产品,我们可以找到像这样的制造商:

SELECT m.name
FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id)
 pname ON true
WHERE pname IS NULL;
```s

# 关于在字段使用json字段类型,其数据为多层嵌套,使用LATERAL

```sql
with

json_table as (select id,round((random()*100)::numeric,2) as score,'{
    "grade": [
        {
            "min": 100,
            "max": 80,
            "name": "优秀"
        },
        {
            "min": 80,
            "max": 60,
            "name": "良好"
        },
        {
            "min": 80,
            "max": 60,
            "name": "不及格"
        }
    ]
}'::json as tag from generate_series(1,100) as t(id))

--select * from json_table

select id,score,grade_s.*  from json_table, LATERAL json_to_recordset(json_table.tag->'grade'::text) grade_s(min integer, max integer,name varchar)
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐