【问题标题】:PostgreSQL - Returning the results of multiple arbitrary sub-queriesPostgreSQL - 返回多个任意子查询的结果
【发布时间】:2015-05-06 03:05:28
【问题描述】:

就像问题的标题所暗示的那样,我正在尝试获取一些任意子查询并将它们组合成一个大型查询。

理想情况下,我希望将数据作为单个记录返回,每一列都是子查询之一的结果。例如

|   sub-query 1   |   sub-query 2   |      ...
|-----------------|-----------------|-----------------
| (array of rows) | (array of rows) |      ...

子查询本身是在 Node 应用程序中使用 Knex.js 构建的,并且完全是任意的。我已经非常接近正确的解决方案了,但我遇到了障碍。

我当前的实现有这样的最终查询:

SELECT
  array_agg(sub0.*) as s0,
  array_agg(sub1.*) as s1,
  ...
FROM
  (...) as sub0,
  (...) as sub1,
  ...
;

这主要是有效的,但会导致输出中出现大量重复。在我的测试过程中,我发现它返回的记录使得每条记录的重复次数等于没有重复记录的返回次数。例如,应返回 10 条记录的子查询将返回 100(每条记录重复 10 次)。

我还没有弄清楚为什么会发生这种情况或如何修复查询以不解决问题。

到目前为止,我只能确定:

  • 单独查询时子查询返回的记录数正确
  • 重复不是由子查询之间的交叉引起的
    • 即子查询包含其他子查询中存在的行

提前致谢。

【问题讨论】:

  • 当您在每个子查询中有 10 条记录时看到总共 100 条记录的原因是您正在执行两个子查询的隐式交叉连接。交叉连接返回两个表(或派生表)的笛卡尔积。换句话说,来自 sub0 的每条记录都连接到来自 sub1 的每条记录。

标签: node.js postgresql postgresql-9.3 knex.js


【解决方案1】:

您还可以将row_number 添加到子查询中,并将该列用于外部联接表(而不是交叉联接):

SELECT
  array_agg(sub0.*) as s0,
  array_agg(sub1.*) as s1
FROM
  (SELECT row_number() OVER (), * FROM (VALUES (1, 'x'),(2, 'y')) t) as sub0
  FULL OUTER JOIN
  (SELECT row_number() OVER (), * FROM (VALUES ('a', 3), ('b', 4), ('c', 5)) t1) as sub1
  ON sub0.row_number=sub1.row_number
;

             s0             |               s1                
----------------------------+---------------------------------
 {"(1,1,x)","(2,2,y)",NULL} | {"(1,a,3)","(2,b,4)","(3,c,5)"}
(1 row)

【讨论】:

    【解决方案2】:

    只需将任意查询放在选择列表中:

    with sq1 as (
        values (1, 'x'),(2, 'y')
    ), sq2 as (
        values ('a', 3), ('b', 4), ('c', 5)
    )
    select
        (select array_agg(s.*) from (select * from sq1) s) as s0,
        (select array_agg(s.*) from (select * from sq2) s) as s1
    ;
            s0         |            s1             
    -------------------+---------------------------
     {"(1,x)","(2,y)"} | {"(a,3)","(b,4)","(c,5)"}
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-25
    • 2020-10-23
    • 2020-11-25
    相关资源
    最近更新 更多