2017-09-06 183 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你的问题听起来像一个不好的数据库设计:我会把这些列移动到一个表中,在这个表中你可以通过使用一个组或类似的东西来完成这个操作。此外,我会做一个单独的脚本字符串连接。 但是,这是我的方式:)

相关问题