2015-04-01 61 views
1

我有一個後續到this question其中我產生這種類型的表的陣列:從數組生成在大小兩個postgres的唯一組合

val | fkey | num 
------------------ 
1 | 1 | 10 
1 | 2 | 9 
1 | 3 | 8 
2 | 3 | 1 

在將所得返回行想是這樣的( fkeys基本上會聚到一個列表):

1 | [1,2,3] 

我想要做的就是修改與相應的查詢到的值在「NUM」列。也就是說,我想要的東西是這樣的:

1 | [1,2] | [10, 9] 
1 | [1,3] | [10, 8] 
1 | [2,3] | [9, 8] 

返回查詢中第三列的排序並沒有打擾我。現在,我有這樣的事情:

SELECT val, array_agg(fkey), array_agg(num) 
FROM mytable 
GROUP BY val 
Having Count(fkey) > 1 

但是返回更多的東西一樣:

1 | [1,2,3] | [10, 9, 8] 

這將是確定的,但我不能輕易告訴其中第三陣列中的數字來自什麼fkey(如果有意義的話)。像這樣將努力跟蹤它:

1 | [1,2,3] | [10 - 1, 9 - 2, 8 - 3] 

我不知道什麼是最好的方式去這樣做的,但我願意接受建議。

編輯:我在Postgres 9.3.6。表定義爲:

awesome-db=# \d mytable 
Table "public.mytable" 
Column | Type | Modifiers 
----------+---------+----------- 
val  | bytea | not null 
fkey  | uuid | not null 
num  | integer | not null 
Indexes: 
"comp_key" UNIQUE CONSTRAINT, btree (fkey, num, val) 
"fingerprint_index" btree (val) 
+0

在同一個'SELECT'列表中的兩個'array_agg()'調用以相同的順序執行元素,除非通過將'ORDER BY'添加到函數參數中指示。所以你*可以*告訴兩個數組中的哪些元素合併在一起,並且你的當前函數應該完成這項工作。我錯過了什麼? – 2015-04-01 08:08:39

+1

通常,像這樣的問題需要您提供表定義(psql中的'\ d mytable')和您的Postgres版本。 – 2015-04-01 08:23:20

+1

在psql中複製/粘貼從'\ d mytable'得到的內容* * * * * * * * * *否則我們無法確定完整的圖片。例如,我仍然不知道你的列是否被定義爲「NOT NULL」。 – 2015-04-02 02:46:29

回答

1

你需要一個self join使用row_number

select t1.val,t1.fkey||','||t2.fkey,t1.num||','|| t2.num 
from (select row_number() over(order by val) rn, 
     val, 
     fkey, 
     num 
from mytable) t1 
join (select row_number() over(order by val) rn, 
     val, 
     fkey, 
     num 
from mytable) t2 
on t1.val=t2.val and t1.rn<t2.rn 

SQLFIDDLE DEMO

1

你有什麼你問什麼:元素的順序在兩個數組對應。

你的第一個想法:

隨着對組合的所有列(val, fkey, num)NOT NULL的限制,你會得到兩個元素(小(num, fkey)第一)的陣列,像這樣的UNIQUE約束:

SELECT t1.val 
    , ARRAY[t1.num, t2.num] AS nums 
    , ARRAY[t1.fkey, t2.fkey] AS fkeys 
FROM mytable t1 
JOIN mytable t2 USING (val) 
WHERE (t1.num, t1.fkey) < (t2.num, t2.fkey); 

或者您第二個想法:

SELECT val, array_agg(num) AS nums, array_agg(num::text || ' - ' || fkey) AS fkeys 
FROM (
    SELECT * 
    FROM mytable 
    ORDER BY num, fkey 
    ) sub 
GROUP BY val 
HAVING count(*) > 1; 

SQL Fiddle.

+0

我添加了一些信息 - 唯一的約束是在所有三列之間。在我的定義中可以重複(val,fkey)。 – 2015-04-01 16:40:24

相關問題