PostgreSQL DISTINCT 和 DISTINCT ON
2019-10-22 15:38 abce 阅读(3994) 评论(0) 编辑 收藏 举报select语句中,使用distinct关键字,在处理
select list
后,结果表可以选择消除重复的行。在
SELECT
之后直接写入
DISTINCT
关键字以指定此关键字:
1 | SELECT DISTINCT select_list ... |
(可以使用关键字
ALL
代替
DISTINCT
来指定保留所有行的默认行为)
显然,如果两行至少有一个列值不同,则认为它们是不同的。在此比较中,将空值视为相等。
另外,一个任意表达式可以确定哪些行被认为是不同的:
1 | SELECT DISTINCT ON (expression [, expression ...]) select_list ... |
这里的
expression
是一个针对所有行求值的任意值表达式。
一组所有表达式均相等的行被视为重复行,并且仅该集合的第一行保留在输出中。请注意,除非查询在足够的列上排序以保证到达
DISTINCT
过滤器的行的唯一顺序,否则集合的“第一行”是不可预测的。(
DISTINCT ON
处理在
ORDER BY
排序之后进行)
DISTINCT ON
子句不是
SQL
标准的一部分,有时由于其结果的不确定性而有时被认为是不良样式。通过明智地使用
GROUP BY
和
FROM
中的子查询,可以避免这种构造,但是它通常是最方便的选择。
1 2 3 4 5 6 7 8 9 10 11 12 | create table t_distinct(a int ,b int ,c int ); insert into t_distinct values (1,2,3); insert into t_distinct values (2,3,4); insert into t_distinct values (3,4,5); insert into t_distinct values (2,2,3); insert into t_distinct values (3,3,4); insert into t_distinct values (4,4,5); insert into t_distinct(a,b) values (5,6); insert into t_distinct(a,b) values (5,6); insert into t_distinct(a,b) values (6,7); |
1.返回所有记录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # select a,b,c from t_distinct; a | b | c ---+---+--- 1 | 2 | 3 2 | 3 | 4 3 | 4 | 5 2 | 2 | 3 3 | 3 | 4 4 | 4 | 5 5 | 6 | 5 | 6 | 6 | 7 | (9 rows ) # select all a,b,c from t_distinct; a | b | c ---+---+--- 1 | 2 | 3 2 | 3 | 4 3 | 4 | 5 2 | 2 | 3 3 | 3 | 4 4 | 4 | 5 5 | 6 | 5 | 6 | 6 | 7 | (9 rows ) |
2.返回 a,b,c 唯一值。(这里NULL视为相等)
1 2 3 4 5 6 7 8 9 10 11 12 | # select distinct a,b,c from t_distinct; a | b | c ---+---+--- 2 | 2 | 3 5 | 6 | 1 | 2 | 3 6 | 7 | 3 | 3 | 4 4 | 4 | 5 3 | 4 | 5 2 | 3 | 4 (8 rows ) |
3.返回a唯一的任意行
1 2 3 4 5 6 7 8 9 10 | # select distinct on (a) a,b,c from t_distinct; a | b | c ---+---+--- 1 | 2 | 3 2 | 2 | 3 3 | 3 | 4 4 | 4 | 5 5 | 6 | 6 | 7 | (6 rows ) |
使用窗口函数可以达到类似效果,但是可以确定返回哪行,因此也更慢一些:
1 2 3 4 5 6 7 8 9 10 | # select * from ( select row_number() over (partition by a) as rn, * from t_distinct) t where rn=1; rn | a | b | c ----+---+---+--- 1 | 1 | 2 | 3 1 | 2 | 2 | 3 1 | 3 | 3 | 4 1 | 4 | 4 | 5 1 | 5 | 6 | 1 | 6 | 7 | (6 rows ) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # select distinct on (a,b) a,b,c from t_distinct; a | b | c ---+---+--- 1 | 2 | 3 2 | 2 | 3 2 | 3 | 4 3 | 3 | 4 3 | 4 | 5 4 | 4 | 5 5 | 6 | 6 | 7 | (8 rows ) #这里 NULL 视为相等 # select distinct on (c) a,b,c from t_distinct; a | b | c ---+---+--- 1 | 2 | 3 3 | 3 | 4 3 | 4 | 5 5 | 6 | (4 rows ) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
2015-10-22 Symantec Backup Exec(BE)的启停
2015-10-22 卸载linux订阅包