单个选择列表中的SQL多个UNNEST

时间:2014-04-11 04:37:12

标签: sql postgresql unnest set-returning-functions

我正在实施一个查询系统。我实现了不需要的功能。 现在用户询问在单个select语句中使用多个unfst。 我使用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正在做正确的事还是只是一个bug?我没有在ANSI文档或PostgreSQL文档中找到明确的描述。

1 个答案:

答案 0 :(得分:7)

这并不是关于不必要的,而是关于PostgreSQL在SELECT列表中对多个集合返回函数的非常奇怪的处理。 SELECT中的集合返回函数不属于ANSI SQL标准。

您会发现LATERAL次查询的行为更加明智,这应该比FROM中尽可能使用集合返回函数更受欢迎:

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

e.g。

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