【问题标题】:Why are "subqueries used as an expression" allowed to return a SETOF something but not a TABLE?为什么“子查询用作表达式”允许返回 SETOF 的东西而不是 TABLE?
【发布时间】:2018-08-10 00:51:01
【问题描述】:

所以我有一个包含一些整数数组的表。

CREATE TABLE arrays (
  nums int[],
  id serial PRIMARY KEY
);

INSERT INTO arrays VALUES
  ('{1, 5, 72}', 1),
  ('{3}', 2),
  ('{32, 6}', 3);

如果我想将这些数组元素分散到单独的行中,我可以使用返回 SETOF INT 的函数来实现,例如 unnest

SELECT
  id,
  unnest(nums)
FROM arrays;

-- id   unnest
-- 1    1
-- 1    5
-- 1    72
-- 2    3
-- 3    32
-- 3    6

但我一直认为 SELECT 子句中的子查询必须返回单个值!然而unnest 正在返回多个值。 Postgres 只是通过复制每个值的行来处理它。但是如果我尝试另一个返回多个值的子查询,像这样:

SELECT
  a.id,
  (SELECT a.nums[1] UNION SELECT a.nums[2])
FROM arrays a;

-- ERROR: more than one row returned by a subquery used as an expression

这给出了一个错误。似乎应该以类似于unnest 的方式处理它。 为什么unnest 允许返回多个值但不允许返回这个?

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    这是一个 PostgreSQL 疣^H^H^H^H 功能。

    其实是documented:

    返回集合的函数也可以在查询的选择列表中调用。对于查询自己生成的每一行,调用集合返回函数,并为函数结果集中的每个元素生成一个输出行。

    [...]

    PostgreSQL 在查询的选择列表中的集合返回函数的行为几乎与将集合返回函数写入 LATERAL FROM 子句项中的行为几乎完全相同。

    请注意,当SELECT 列表中有几个 set-returning 函数时的行为在 v10 中发生了变化;请参阅发行说明。

    我建议你不要使用它,并将这些函数放在它们所属的 FROM 列表中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多