Postgresql数据中的LATERAL
postgresql LATERAL的使用
在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)

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