假设我有这些行:
第 1 行apple,watermelon,pineapple
第 2 行apple,pineapple,orange
第 3 行apple,blue berry
我想创建从所有行中获取唯一值的单个文本值。
我们如何使用查询来做到这一点?
预期结果:
apple,watermelon,pineapple,orange,blue berry
假设我有这些行:
第 1 行apple,watermelon,pineapple
第 2 行apple,pineapple,orange
第 3 行apple,blue berry
我想创建从所有行中获取唯一值的单个文本值。
我们如何使用查询来做到这一点?
预期结果:
apple,watermelon,pineapple,orange,blue berry
尝试这个:
select array_agg(val) from (
select distinct unnest(string_to_array(my_column, ',')) val from my_table) x
正在发生的事情的细分:
string_to_array()
使用指定的分隔符将字符串拆分为真正的数组unnest()
将数组转换为单独的行 - 每个元素一个distinct
删除重复的行array_agg()
将所有行连接成一个 CSV 字符串(通常你会使用一个group by
子句,但这里不需要,因为只有一个组)您可以使用以下函数将行值拆分为 ' ,
'
CREATE FUNCTION [dbo].[ConvertToTable]
(
@delimiter char(1),
@string nvarchar(MAX)
)
RETURNS @Values TABLE ( VALUE NVARCHAR(MAX) )
AS BEGIN
SET @string = @string + @delimiter ;
WITH Nbrs_3 ( n ) AS ( SELECT 1 UNION SELECT 0 ) ,
Nbrs_2 ( n ) AS ( SELECT 1 FROM Nbrs_3 n1 CROSS JOIN Nbrs_3 n2 ) ,
Nbrs_1 ( n ) AS ( SELECT 1 FROM Nbrs_2 n1 CROSS JOIN Nbrs_2 n2 ) ,
Nbrs_0 ( n ) AS ( SELECT 1 FROM Nbrs_1 n1 CROSS JOIN Nbrs_1 n2 ) ,
Nbrs ( n ) AS ( SELECT 1 FROM Nbrs_0 n1 CROSS JOIN Nbrs_0 n2 )
INSERT @Values ( [VALUE] )
SELECT SUBSTRING(@string, n + 1, CHARINDEX(@delimiter, @string, n + 1) - n - 1)
FROM ( SELECT 0 AS 'n' UNION ALL
SELECT TOP ( LEN(@string) - 1 ) ROW_NUMBER() OVER ( ORDER BY n ) AS 'n' FROM Nbrs
) x
WHERE SUBSTRING(@string, n, 1) = @delimiter
OR n = 0
RETURN
END
并使用以下代码获取结果..
DECLARE @unique_value NVARCHAR(MAX)
WITH cte AS (
SELECT 1 AS id, 'apple,watermelon,pineaple' AS String
UNION
SELECT 2 ,'apple,pineaple,orange'
UNION
SELECT 3 ,'apple,blue berry'
)
SELECT @unique_value= COALESCE(@unique_value+',','')+[VALUE] FROM [cte]
CROSS APPLY [dbo].[ConvertToTable](',',[String]) AS CTT
GROUP BY [VALUE]
SELECT @unique_value
更新:我没有注意到这是关于 postgresql 的。我已经给出了 MSSQL 的答案,如果你可以在 postgresql 中做同样的事情。这个方法可以帮助你..
尝试这个:
SELECT ARRAY(SELECT distinct regexp_split_to_table(myTable.columns, E',') AS split_columns FROM myTable);