我有一个带ID的简单表和一些以空格分隔的段:
id | segments
-------------------------------+-----------------------
2A3A3362051D43-6000014002B3C4 | 73024 73025
2A399D20051D96-4000010002782A | 96878 92779 73024 73025
2A3747D3051DE0-40000100032E40 | 139313
29C1D823851DDF-400001200FD641 | 139313
问题在于其中一些ID会被重复:
id | segments
-------------------------------+--------------------------
27295CD0851AB2-400000E01059BF | 139313
27295CD0851AB2-400000E01059BF | 139313
27295CD0851AB2-400000E01059BF | 139313 92779 73024 73025
27295CD0851AB2-400000E01059BF | 139313
27295CD0851AB2-400000E01059BF | 139313
问题是如何删除不必要的行并且每个ID只保留一行,同时还保留所有段(它们是随机的,我必须保留每一段)段存储为文本,因此简单的字符串连接将工作
答案 0 :(得分:2)
这是一种非常糟糕的数据格式。您应该有一个单独的表,每个ID和每个段有一行。在单独的列表中存储事物列表并不能很好地利用关系数据库。将数值存储为字符串甚至更糟。
也就是说,有时您会遇到特定格式的数据。您可以取消字符串,获取不同的值,然后重新聚合以执行您想要的操作:
select id, string_agg(segment, ' ')
from (select distinct id, unnest(string_to_array(segments, ' ')) as segment
from t
) t
group by id;
答案 1 :(得分:0)
假设您有一个简单的文本列:
SELECT id, string_agg(DISTINCT seg) AS segments
FROM tbl
, unnest(string_to_array(segments, ' ')) seg
GROUP BY 1;
在第9.3页中,使用LATERAL
连接而不是在SELECT
列表中调用set-returning函数。相关答案详情如下:
考虑normalizing您的桌面布局。