2010-04-01 81 views
169

我有一個表,我想每個ID拉字段值連接一行。Postgresql GROUP_CONCAT等效?

在我的表,例如,我有這樣的:

TM67 | 4 | 32556 
TM67 | 9 | 98200 
TM67 | 72 | 22300 
TM99 | 2 | 23009 
TM99 | 3 | 11200 

而且想我輸出:

TM67 | 4,9,72 | 32556,98200,22300 
TM99 | 2,3 | 23009,11200 

在MySQL中我能夠使用聚合函數GROUP_CONCAT,但這似乎不工作在這裏...是否有相當於PostgreSQL,或另一種方式來實現這一目標?

+0

不是一個答案,但檢查出http://www.postgresonline.com/journal/index.php? /archives/14-CrossTab-Queries-in-PostgreSQL-using-tablefunc-contrib.html。 – Kuberchaun 2010-04-01 14:21:49

+1

http://stackoverflow.com/questions/1943433/postgresql-concat-ws-like-function – 2010-04-01 15:41:26

+0

可能重複[在SQL Server中模擬組\ _concat MySQL函數?](http://stackoverflow.com/questions/451415/simulating-group-concat-mysql-function-in-sql-server) – ntalbs 2015-02-10 03:49:09

回答

155

這可能是一個很好的起點(版本8.4+只):

SELECT id_field, array_agg(value_field1), array_agg(value_field2) 
FROM data_table 
GROUP BY id_field 

array_agg返回一個數組,但你可以強制轉換爲需要的文本和編輯(見澄清,下同)。

此前8.4版本,你必須定義它自己使用前:

CREATE AGGREGATE array_agg (anyelement) 
(
    sfunc = array_append, 
    stype = anyarray, 
    initcond = '{}' 
); 

(從PostgreSQL文檔意譯)

澄清:

  • 鑄造的結果數組到文本是生成的字符串以花括號開始和結束。這些大括號需要通過某種方法刪除,如果他們不需要。
  • 將ANYARRAY投射到TEXT最能模擬CSV輸出,因爲包含嵌入逗號的元素在標準CSV樣式的輸出中被雙引號引用。無論是array_to_string()還是string_agg()(9.1中添加了「group_concat」函數)都會引用帶有嵌入逗號的字符串,從而導致結果列表中的元素數量不正確。
  • 新的9.1 string_agg()函數不會先將內部結果轉換爲TEXT。所以如果value_field是一個整數,那麼「string_agg(value_field)」會產生一個錯誤。 「string_agg(value_field :: text)」將是必需的。 array_agg()方法在聚合之後只需要一次強制轉換(而不是每個值的強制轉換)。
+0

而在9。0您將有LISTAGG() – 2010-04-01 16:55:29

+4

要獲得CSV查詢應該是: SELECT id_field,array_to_string(ARRAY_AGG(value_field1), ' '),array_to_string(ARRAY_AGG(value_field2),'') FROM data_table GROUP BY id_field – Nux 2012-02-16 16:08:34

+2

在這裏的所有情況下都不能使用array_to_string。如果您的value_field包含嵌入的逗號,則結果CSV不正確。使用array_agg()並將其轉換爲TEXT可以正確引用帶有嵌入逗號的字符串。唯一需要注意的是,它還包括起始和結束花括號,因此我的聲明是「並根據需要進行編輯」。我會編輯以澄清這一點。 – 2012-02-21 20:00:56

30
SELECT array_to_string(array(SELECT a FROM b),', '); 

也將這樣做。

+4

這個也在9.0之前工作 - 用8.4測試它。 5 – chrpes 2013-08-16 09:59:25

+0

超凡!適用於我。 Teste也是Postgres 8.3.6。坦克! – vandersondf 2014-06-18 19:02:29

+0

是否可以在[此評論]中執行某些操作(http://stackoverflow.com/questions/2560946/postgresql-group-concat-equivalent#comment23843695_8803563),您是按照某個順序進行聚合的?你將如何處理一列的分組和另一列的排序(例如,連接縱向數據集內的變量)? – 2015-01-08 18:22:26

178

Since 9.0這是更簡單:

SELECT id, 
     string_agg(some_column, ',') 
FROM the_table 
GROUP BY id 
+18

請注意,該語法還允許您指定字符串(或數組,使用'array_agg')的值的順序,例如'string_agg(some_column,','ORDER BY some_column)'或者甚至'string_agg(surname ||','|| forename,';'ORDER BY surname,forename)' – IMSoP 2013-05-16 14:33:36

+0

@a_horse_with_no_name我看到很多關於你的好帖子所以我正在處理各種Postgres問題。我沒有辦法在您的個人資料中與您聯繫。您是否願意溝通/處理SO之外的項目?如果不是,請通過評論來表示歉意。如果您願意接受SO之外的合作/工作,如果可以的話,您可以通過我的個人資料與我聯繫:http://stackoverflow.com/users/2565593/steve-midgley - 您在這裏完成了令人驚歎的工作 - 謝謝您! (對於編輯,我依靠這樣的元評論來留下評論:http://meta.stackexchange.com/a/58715/278168) – 2015-02-14 20:48:47

8

嘗試這樣的:

select field1, array_to_string(array_agg(field2), ',') 
from table1 
group by field1; 
相關問題