将不同的行值组合成一个字符串 - 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 或类似的东西来执行此操作。此外,我会在单独的脚本上进行字符串连接。 但这是我做事的方式:)