使用postgresql TEXT类型按字段排序时如何删除重复项?

Posted

技术标签:

【中文标题】使用postgresql TEXT类型按字段排序时如何删除重复项?【英文标题】:How to remove duplicates when sorting by field with postgresql TEXT type? 【发布时间】:2021-08-21 12:11:12 【问题描述】:

假设有一个带有字段昵称、全名的个人资料板。昵称字段是文本。我想以不区分大小写的方式按 TEXT 字段对该表进行排序,删除昵称字段的重复项。我该怎么做?

有这样的记录

CREATE TABLE profile(
    nickname text,
    fullname text );

SELECT DISTINCT * FROM profile
ORDER BY  lower(nickname) 

显示错误ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list

不幸的是,lower() 不适用于 varchar(它会写入与 utf8 相关的错误),并且无法使用 CITEXT 扩展名。如何解决这个问题?

【问题讨论】:

请提供样本数据和期望的结果。 “去除昵称字段的重复项”是什么意思? @Anton 提供了一些示例数据和预期结果。再次阅读您的问题后,我不确定我是否正确。也许一个简单的distinct on 就足够了.. 我认为这是 PostgreSQL 中的一个错误。 nickname 确实存在于选择列表中,因此 DBMS 应该能够按 lower(nickname 对其进行排序。顺便说一句,如果我们删除DISTINCT,它确实有效,所以当DISTINCTORDER BY结合使用时,PostgreSQL会不知何故感到困惑。 【参考方案1】:

正如错误消息所示,您不能按不存在的列排序。话虽如此,将 lower 函数添加到 select 子句中,它应该可以工作:

SELECT DISTINCT lower(nickname), fullname 
FROM profile
ORDER BY lower(nickname);

如果您想任意消除重复的昵称,请尝试DISTINCT ON

SELECT DISTINCT ON (lower(nickname)) * 
FROM profile
ORDER BY lower(nickname);

【讨论】:

【参考方案2】:
SELECT DISTINCT lower(nickname),* FROM profile
ORDER BY  lower(nickname);

如错误所写

【讨论】:

以上是关于使用postgresql TEXT类型按字段排序时如何删除重复项?的主要内容,如果未能解决你的问题,请参考以下文章

CONVERT_TEXT(转换为可排序格式)

postgresql 修改字段类型为数组类型(text 改为 text[] )

postgresql 修改字段类型为数组类型(text 改为 text[] )

日期和按日期排序时的postgresql案例

elasticsearch text类型排序

转义制表符 PostgreSQL