Postgres消除了具有相同ID的多行

时间:2014-11-28 16:46:42

标签: sql postgresql

我有一个带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只保留一行,同时还保留所有段(它们是随机的,我必须保留每一段)段存储为文本,因此简单的字符串连接将工作

2 个答案:

答案 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您的桌面布局。