Distinct:查詢結果中,去掉了重復的行
1.語法:
SELECT Distinct列名稱 FROM 表名稱;
Distinct 必須放在Select搜索字段的最前面,否則SQL語句會報語法錯誤。
2.示例:
- 2.1簡單建立一個表,填入數據,執行SQL:
Select * From [BlogDemo].[dbo].[People]
,結果如下:
- 2.2 單獨查詢Name字段,執行SQL:
Select Name From [BlogDemo].[dbo].[People]
,結果如下:
- 2.3 上面查詢結果的Name中"李麗"出現了3次,可以使用Distinct 關鍵字去重復,執行SQL:
Select distinct Name From [BlogDemo].[dbo].[People]
,結果如下:
- 2.4 上面查詢結果中可以看到,Distinct 關鍵字去重復的作用實現了。如果在去重復Name的需求下還需要查詢其他所有字段,會出現什么結果,執行SQL:
Select distinct Name,Age,Address From [BlogDemo].[dbo].[People]
,結果如下:
- 2.5 可以看到Distinct 關鍵字去重復作用並沒有什么卵用,當 Distinct 作用在多個字段的時候,它只會將所有字段值都相同的記錄“去重”掉,下面驗證下,在表中在插入一條數據,如下:
- 2.6 新插入數據第8條和第1條數據內容完全相同,再次執行SQL:
Select distinct Name,Age,Address From [BlogDemo].[dbo].[People]
,結果如下:
- 2.7 可以看到第8條數據被去重了,所以:當 Distinct 作用在多個字段的時候,它只會將所有字段值都相同的記錄“去重”掉。在我們實際開發中,表中可能含有多條擁有相同某個字段的記錄,如同示例中的Name字段,如果我們只需要相同Name的一個數據怎么辦呢?
row_number() over() 函數:對結果集的輸出進行編號。返回結果集分區內行的序列號,每個分區的第一行從 1 開始
1.語法:
ROW_NUMBER ( ) OVER ( [ PARTITION BY value_expression , ... [ n ] ] order_by_clause )
2.參數:
PARTITION BY value_expression:將 FROM 子句生成的結果集划分為應用 ROW_NUMBER 函數的分區。 value_expression 指定對結果集進行分區所依據的列。 如果未指定 PARTITION BY,則此函數將查詢結果集的所有行視為單個組。 (PARTITION BY作用相似Group By 分組的效果) 。
order_by_clause:ORDER BY 子句可確定在特定分區中為行分配唯一 ROW_NUMBER 的順序。 它是必需的。
3.示例:
- 3.1 依舊使用上面的People表,先不加PARTITION BY分組的效果,執行SQL:
Select *,ROW_NUMBER() OVER(Order By Id) as row From [BlogDemo].[dbo].[People]
,可以看到查詢的結果集有8組,最后一列加入了row字段標識,結果如下:
- 3.2 加入PARTITION BY分組的效果,執行SQL:
Select *,ROW_NUMBER() OVER(Partition By Name Order By Id) as row From [BlogDemo].[dbo].[People],可以看到這次結果集只有4組,Name為"李麗"全部被標識為4組,結果如下:
- 3.3 如果我們只取Name字段相同數據的一組,只要加一個篩選條件分組row為1即可,執行SQL:
Select * From (Select *,ROW_NUMBER() OVER(Partition By Name Order By Id) as row From [BlogDemo].[dbo].[People]) p Where p.row=1
,這時候結果集中Name不會出現相同的數據了,結果如下:
總結:
Distinct 和 row_number() over() 都有將數據去重復的作用,但Distinct 只能作用於單個字段查詢結果集去重復,若針對多個字段查詢的結果集去重復,需要所有字段都重復才可以去重復。row_number() over() 函數具有分組效果,無論是對於單字段還是多字段查詢結果集去重復都可以做到。