将不同的行值组合成一个字符串 - sql
我想在每一行取单元格并将它们变成一串名称......我的方法已经处理了套管。将不同的行值组合成一个字符串 - 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'
令牌的顺序并不重要,只要所有的唯一值仅一次返回。
感谢
规范化表结构,从该表中选择不同的名称值,创建聚合字符串(例如,参见How to concatenate strings of a string field in a PostgreSQL 'group by' query?)功能,并应用该功能。除了创建集合函数之外,这可以全部在单个语句或视图中完成。
谢谢 - 不知道我是如何错过这个问题的;我花了好几个小时浏览类似的问题。 – MREES
我会通过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;
在PG 8.2中,string_agg()函数不可用。 –
@rd_nielsen。 。 。还有第二个答案。 –
是的; concat()函数也不在PG 8.2中。我认为使用string_agg()方法是最好的,但需要添加自定义聚合函数(这在PG中非常简单)。 –
我拿出你最好的选择! :)
以下查询返回四列(我命名为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你的问题听起来像一个不好的数据库设计:我会把这些列移动到一个表中,在这个表中你可以通过使用一个组或类似的东西来完成这个操作。此外,我会做一个单独的脚本字符串连接。 但是,这是我的方式:)
这似乎是一个坏的数据库设计,我认为你需要一个应用程序层。 –