将不同的行值组合成一个字符串 - sql
combine distinct row values into a string - sql
我想把每一行的单元格做成一串名字...我的方法已经处理了大小写。
例如table;
'john' | | 'smith' | 'smith'
'john' | 'paul' | | 'smith'
'john' | 'john' | 'john' |
returns:
'john smith'
'john paul smith'
'john'
这需要 运行 postgres 的 postgreSQL 8.2.15,所以我无法使用 CONCAT 等潜在有用的函数,并且数据在 greenplum 数据库中。
或者,直接删除字符串列表中重复标记的方法可以让我获得更大的 objective。例如:
'john smith john smith'
'john john smith'
'smith john smith'
returns
'john smith'
'john smith'
'smith john'
标记的顺序并不重要,只要返回所有唯一值即可,一次即可。
谢谢
规范化您的 table 结构,select 与 table 不同的名称值,创建一个聚合字符串的函数(参见 How to concatenate strings of a string field in a PostgreSQL 'group by' query?),然后应用那个功能。除了创建聚合函数外,这一切都可以在单个语句或视图中完成。
我会通过反透视数据然后重新聚合来做到这一点:
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;
我已经为你想出了一个解决方案! :)
以下查询 returns 四列(我将其命名为 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" 行替换为这一行:
SELECT trim(both ' ' FROM (COALESCE(t1.col_1, '') || ' ' || COALESCE(t2.col_2, '') || ' ' || COALESCE(t3.col_3, '') || ' ' || COALESCE(t4.col_4, '')))
根据文档,这应该适用于您的 postgres 版本:
[对于 trim 和连接函数]
https://www.postgresql.org/docs/8.2/static/functions-string.html
//************************************************ ********
[用于合并函数]
https://www.postgresql.org/docs/8.2/static/functions-conditional.html
如果我对您有帮助,请告诉我:)
P.S。您的问题听起来像是一个糟糕的数据库设计:我会将这些列移动到 table 上,您可以在其中使用 group by 或类似的东西来执行此操作。此外,我会在单独的脚本上进行字符串连接。
但这是我做事的方式:)
我想把每一行的单元格做成一串名字...我的方法已经处理了大小写。
例如table;
'john' | | 'smith' | 'smith'
'john' | 'paul' | | 'smith'
'john' | 'john' | 'john' |
returns:
'john smith'
'john paul smith'
'john'
这需要 运行 postgres 的 postgreSQL 8.2.15,所以我无法使用 CONCAT 等潜在有用的函数,并且数据在 greenplum 数据库中。
或者,直接删除字符串列表中重复标记的方法可以让我获得更大的 objective。例如:
'john smith john smith'
'john john smith'
'smith john smith'
returns
'john smith'
'john smith'
'smith john'
标记的顺序并不重要,只要返回所有唯一值即可,一次即可。
谢谢
规范化您的 table 结构,select 与 table 不同的名称值,创建一个聚合字符串的函数(参见 How to concatenate strings of a string field in a PostgreSQL 'group by' query?),然后应用那个功能。除了创建聚合函数外,这一切都可以在单个语句或视图中完成。
我会通过反透视数据然后重新聚合来做到这一点:
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;
我已经为你想出了一个解决方案! :)
以下查询 returns 四列(我将其命名为 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" 行替换为这一行:
SELECT trim(both ' ' FROM (COALESCE(t1.col_1, '') || ' ' || COALESCE(t2.col_2, '') || ' ' || COALESCE(t3.col_3, '') || ' ' || COALESCE(t4.col_4, '')))
根据文档,这应该适用于您的 postgres 版本:
[对于 trim 和连接函数]
https://www.postgresql.org/docs/8.2/static/functions-string.html
//************************************************ ********
[用于合并函数]
https://www.postgresql.org/docs/8.2/static/functions-conditional.html
如果我对您有帮助,请告诉我:)
P.S。您的问题听起来像是一个糟糕的数据库设计:我会将这些列移动到 table 上,您可以在其中使用 group by 或类似的东西来执行此操作。此外,我会在单独的脚本上进行字符串连接。 但这是我做事的方式:)