7

我正在实施一个查询系统。我实现了 unnest 功能。现在用户询问是否在单个 select 语句中使用多个 unnest。我使用 PostgreSQL 作为一种指南,因为大多数用户在我们的查询系统之前使用它。

PostgreSQL 有这样奇怪的行为:

postgres=# select unnest(array[1,2]), unnest(array[1,2]);
 unnest | unnest
--------+--------
      1 |      1
      2 |      2
(2 rows)

postgres=# select unnest(array[1,2]), unnest(array[1,2,3]);
 unnest | unnest
--------+--------
      1 |      1
      2 |      2
      1 |      3
      2 |      1
      1 |      2
      2 |      3
(6 rows)

我的实现总是生成为笛卡尔积。我想知道,这背后的正确逻辑是什么?PostgreSQL 是在做正确的事还是只是一个错误?我没有在 ANSI 文档或 PostgreSQL 文档中找到明确的描述。

4

1 回答 1

9

这不是关于 unnest 本身,而是关于 PostgreSQL 对SELECT列表中多个集合返回函数的非常奇怪的处理。中的集合返回函数SELECT不是 ANSI SQL 标准的一部分。

您会发现查询的行为更加理智,这应该比尽可能多地LATERAL使用集合返回函数更可取:FROM

select a, b FROM unnest(array[1,2]) a, LATERAL unnest(array[1,2,3]) b;

例如

regress=> select a, b FROM unnest(array[1,2]) a, LATERAL unnest(array[1,2,3]) b;
 a | b 
---+---
 1 | 1
 1 | 2
 1 | 3
 2 | 1
 2 | 2
 2 | 3
(6 rows)

我仍然使用多个返回集合的函数的唯一一次SELECT是当我想将返回相同行数的函数中的值配对时。在 9.4 中,这种需求将消失,具有多参数unnest并支持WITH ORDINALITY.

于 2014-04-11T05:24:47.593 回答