2017-09-06 182 views
0

我想在每一行取單元格並將它們變成一串名稱......我的方法已經處理了套管。將不同的行值組合成一個字符串 - sql

例如,表;

'john' |  | 'smith' | 'smith'  
'john' | 'paul' |   | 'smith' 
'john' | 'john' | 'john' |  

回報:

'john smith' 
'john paul smith' 
'john' 

這將需要運行的Postgres的PostgreSQL的8.2.15,所以我不能利用的潛在有用的功能,如CONCAT,而數據則是在Greenplum的數據庫。

或者,直接刪除字符串列表中的重複令牌的方法可以讓我實現更大的目標。例如:

'john smith john smith' 
'john john smith' 
'smith john smith' 

回報

'john smith' 
'john smith' 
'smith john' 

令牌的順序並不重要,只要所有的唯一值僅一次返回。

感謝

+0

這似乎是一個壞的數據庫設計,我認爲你需要一個應用程序層。 –

回答

0

我會通過unpivoting的數據,然後再凝聚做到這一點:

select id, string_agg(distinct col) 
from (select id, col1 from t union all 
     select id, col2 from t union all 
     select id, col3 from t union all 
     select id, col4 from t 
    ) t 
where col is not null 
group by id; 

這假定每一行都有一個唯一的ID。

你也可以使用一個巨型case

select concat_ws(',', 
       col1, 
       (case when col2 <> col1 then col2 end), 
       (case when col3 <> col2 and col3 <> col1 then col3 end), 
       (case when col4 <> col3 and col4 <> col2 and col4 <> col1 then col4 end) 
       ) as newcol 
from t; 

在古老的版本的Postgres,你可以這句話爲:

select trim(leading ',' from 
      (coalesce(',' || col1, '') || 
      (case when col2 <> col1 then ',' || col2 else '' end) || 
      (case when col3 <> col2 and col3 <> col1 then ',' || col3 else '' end), 
      (case when col4 <> col3 and col4 <> col2 and col4 <> col1 then ',' || col4 else '' end) 
      ) 
      ) as newcol 
from t; 
+0

在PG 8.2中,string_agg()函數不可用。 –

+0

@rd_nielsen。 。 。還有第二個答案。 –

+0

是的; concat()函數也不在PG 8.2中。我認爲使用string_agg()方法是最好的,但需要添加自定義聚合函數(這在PG中非常簡單)。 –

0

我拿出你最好的選擇! :)

以下查詢返回四列(我命名爲col_1,2,3和4),並通過將test_table與自身結合來刪除重複項。

下面是代碼:

SELECT t1.col_1, t2.col_2, t3.col_3, t4.col_4 

FROM (
    SELECT id, col_1 
     FROM test_table 
) AS t1 

LEFT JOIN (
    SELECT id, col_2 
     FROM test_table 
) as t2 

ON (t2.id = t1.id and t2.col_2 <> t1.col_1) 


LEFT JOIN (
    SELECT id, col_3 
     FROM test_table 
) as t3 

ON (t3.id = t1.id and t3.col_3 <> t1.col_1 and t3.col_3 <> t2.col_2) 



LEFT JOIN (
    SELECT id, col_4 
     FROM test_table 
) as t4 

ON (t4.id = t1.id and t4.col_4 <> t1.col_1 and t4.col_4 <> t2.col_2 and t4.col_4 <> t3.col_3); 

如果你想獲得最終的字符串,你剛剛替補「選擇」行這一個:

SELECT trim(both ' ' FROM (COALESCE(t1.col_1, '') || ' ' || COALESCE(t2.col_2, '') || ' ' || COALESCE(t3.col_3, '') || ' ' || COALESCE(t4.col_4, ''))) 

這應該與您當前的版本根據文檔:

[用於修剪和連接功能]

https://www.postgresql.org/docs/8.2/static/functions-string.html

// ****************************************** *********

[用於聚結功能]

https://www.postgresql.org/docs/8.2/static/functions-conditional.html

請讓我知道,如果我一直的幫助:)

PS你的問題聽起來像一個不好的數據庫設計:我會把這些列移動到一個表中,在這個表中你可以通過使用一個組或類似的東西來完成這個操作。此外,我會做一個單獨的腳本字符串連接。 但是,這是我的方式:)

相關問題