PostgreSQL DISTINCT 和 DISTINCT ON


select語句中,使用distinct關鍵字,在處理select list后,結果表可以選擇消除重復的行。在SELECT之后直接寫入DISTINCT關鍵字以指定此關鍵字:

SELECT DISTINCT select_list ...

(可以使用關鍵字ALL代替DISTINCT來指定保留所有行的默認行為)

 

顯然,如果兩行至少有一個列值不同,則認為它們是不同的。在此比較中,將空值視為相等。

 

另外,一個任意表達式可以確定哪些行被認為是不同的:

SELECT DISTINCT ON (expression [, expression ...]) select_list ...

這里的expression是一個針對所有行求值的任意值表達式。 一組所有表達式均相等的行被視為重復行,並且僅該集合的第一行保留在輸出中。請注意,除非查詢在足夠的列上排序以保證到達DISTINCT過濾器的行的唯一順序,否則集合的“第一行”是不可預測的。(DISTINCT ON處理在ORDER BY排序之后進行)

DISTINCT ON子句不是SQL標准的一部分,有時由於其結果的不確定性而有時被認為是不良樣式。通過明智地使用GROUP BYFROM中的子查詢,可以避免這種構造,但是它通常是最方便的選擇。

 

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.返回所有記錄:

# 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視為相等)

# 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唯一的任意行

# 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)

使用窗口函數可以達到類似效果,但是可以確定返回哪行,因此也更慢一些:

# 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)

  

# 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)

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM