用途:本技能讲解 PostgreSQL FROM 子句中的 LATERAL 子查询——允许子查询引用前面 FROM 项的列。每个外层行会重新求值一次子查询,再按标准 JOIN 树方式连接。关键字对 (SELECT ...) 交叉引用子查询是必需的;对函数调用则是可选的。
主要能力与用法:
- 每组取前 N 条:在外层相关子查询中用 ORDER BY + LIMIT k,配合 (parent_id, order_col) 索引可走 Nested Loop + Index Scan,通常比 row_number() 窗口函数快很多。
- 按行展开 JSON 数组:用 LATERAL jsonb_array_elements(e.payload->'items'),最好显式写 LATERAL 以表明交叉引用。
- 逐行 generate_series:用于按行变化的日期区间分桶或补空。
- LEFT JOIN LATERAL (...) ON true:保留外层行、子列为 NULL,常用于找出“没有子记录”的行,以及“每个客户加最近一笔订单”。
- 与相关标量子查询区分:需多行或多列时用 LATERAL,单值用标量子查询。
关键限制与常见错误:FROM outer, LATERAL (...) 会在子查询为空时丢弃外层行,需要保留时应写 LEFT JOIN LATERAL (...) ON true;每个 LATERAL 子查询必须有别名,否则报 42P01;LIMIT 前必须加确定性的 ORDER BY;聚合所有行不要用 LATERAL;纯等值连接用普通 JOIN。相关方法、示例与反模式见资料列出的参考文档。