PostgreSQL - 返回多个任意子查询的结果

时间:2015-03-04 22:13:54

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

就像问题的标题所示,我试图采取一些任意的子查询并将它们组合成一个大的查询。

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

|   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次)。

我还没弄清楚为什么会出现这种情况或者如何修复查询以避免问题。

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

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

提前致谢。

2 个答案:

答案 0 :(得分: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)"}

答案 1 :(得分:0)

此外,您可以向子查询添加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)