【问题标题】:SQL multiple UNNEST in single select list单个选择列表中的 SQL 多个 UNNEST
【发布时间】:2014-05-25 01:52:53
【问题描述】:

我正在实施一个查询系统。我实现了 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 文档中找到明确的描述。

【问题讨论】:

  • 相关答案hereherehere。最后一篇详细介绍了LATERAL 和即将在 9.4 中发布的WITH ORDINALITY
  • 谢谢@Erwin Brandstetter。

标签: sql postgresql unnest set-returning-functions


【解决方案1】:

这不是关于 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

【讨论】:

  • 但在 FROM 子句中他们不能有聚合 unnest(array_agg(id))
  • 请注意,这种奇怪的行为可能会在未来的 PostgreSQL 版本中改变。不要依赖它。
  • @EvanCarroll 对,您需要在子查询中处理它。 (请发布一个新问题并在此处的 cmets 中添加指向它的链接。)
猜你喜欢
  • 1970-01-01
  • 2022-06-23
  • 2011-07-01
  • 2019-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-25
  • 2011-02-01
相关资源
最近更新 更多