2013-03-27 218 views
3

比方说,我有一个简单的表agg_test 3列 - id,column_1column_2。数据集,例如:聚合聚合(ARRAY_AGG)?

id|column_1|column_2 
-------------------- 
1|  1|  1 
2|  1|  2 
3|  1|  3 
4|  1|  4 
5|  2|  1 
6|  3|  2 
7|  4|  3 
8|  4|  4 
9|  5|  3 
10|  5|  4 

这样的查询(带自加入):

SELECT 
    a1.column_1, 
    a2.column_1, 
    ARRAY_AGG(DISTINCT a1.column_2 ORDER BY a1.column_2) 
FROM agg_test a1 
JOIN agg_test a2 ON a1.column_2 = a2.column_2 AND a1.column_1 <> a2.column_1 
WHERE a1.column_1 = 1 
GROUP BY a1.column_1, a2.column_1 

会产生这样的结果:

column_1|column_1|array_agg 
--------------------------- 
     1|  2|  {1} 
     1|  3|  {2} 
     1|  4| {3,4} 
     1|  5| {3,4} 

我们可以看到,值4在连接表中有5个,我们在最后一列有相同的结果。因此,是否有可能以某种方式组的结果通过它,e.g:

column_1|column_1|array_agg 
--------------------------- 
     1|  {2}|  {1} 
     1|  {3}|  {2} 
     1| {4,5}| {3,4} 

感谢您的任何答案。如果有什么不清楚或者能够以更好的方式呈现 - 请在评论中告诉我,我会尽量让这个问题尽可能可读。

回答

4

我不确定您是否可以通过数组进行聚合。如果你能在这里是一种方法:

select col1, array_agg(col2), ar 
from (SELECT a1.column_1 as col1, a2.column_1 as col2, 
      ARRAY_AGG(DISTINCT a1.column_2 ORDER BY a1.column_2) as ar 
     FROM agg_test a1 JOIN 
      agg_test a2 
      ON a1.column_2 = a2.column_2 AND a1.column_1 <> a2.column_1 
     WHERE a1.column_1 = 1 
     GROUP BY a1.column_1, a2.column_1 
    ) t 
group by col1, ar 

另一种方法是使用array_dims到数组值转换为字符串。

+0

谢谢,对我完美的作品。 – Przemek 2013-03-27 15:41:00

2

您也可以尝试这样的事:

SELECT DISTINCT 
    a1.column_1, 
    ARRAY_AGG(a2.column_1) OVER ( PARTITION BY a1.column_1, ARRAY_AGG(DISTINCT a1.column_2 ORDER BY a1.column_2) ) AS "a2.column_1 agg", 
    ARRAY_AGG(DISTINCT a1.column_2 ORDER BY a1.column_2) 
FROM agg_test a1 
JOIN agg_test a2 ON a1.column_2 = a2.column_2 AND a1.column_1 a2.column_1 
WHERE a1.column_1 = 1 
GROUP BY a1.column_1, a2.column_1 
;

(突出显示的是从你张贴在你的问题中查询不同的部分)

以上使用窗口ARRAY_AGG到将a2.column_1的值与其他其他ARRAY_AGG相结合,将后者的结果作为分区标准之一。如果没有DISTINCT,它会为您的示例生成两行{4,5}行。因此,需要DISTINCT来消除重复项。

这里有一个SQL小提琴演示:http://sqlfiddle.com/#!1/df5c3/4

但是请注意,该窗口ARRAY_AGG不能有ORDER BY就像是“正常”的对口。这意味着列表中的a2.column_1值的顺序将是不确定的,尽管在链接的演示中它确实与您预期的输出中的值相匹配。