首頁  >  文章  >  資料庫  >  詳解distinct 和 row_number()和over() 的差別

詳解distinct 和 row_number()和over() 的差別

Y2J
Y2J原創
2017-05-24 13:55:121563瀏覽

這篇文章主要介紹了SQL中詳解distinct 和 row_number()和over() 的差別 和row_number() over() 的區別及用法的相關資料,需要的朋友可以參考下

1 前言

#在咱們編寫SQL 語句操作資料庫中的資料的時候,有可能會遇到一些不太爽的問題,例如對於同一欄位擁有相同名稱的記錄,我們只需要顯示一條,但實際上資料庫中可能含有多筆擁有相同名稱的記錄,從而在檢索的時候,顯示多筆記錄,這就有違咱們的初衷啦!因此,為了避免這種情況的發生,咱們就需要進行「去重」處理啦,那麼何為「去重」呢?說穿了,就是對同一欄位讓擁有相同內容的記錄只顯示一筆記錄。

那麼,要如何實現「去重」的功能呢?對此,咱們有兩種方式可以實現該功能。

第一種,在寫select 語句的時候,加入詳解distinct 和 row_number()和over() 的差別 關鍵字;

#第二種,在寫select 語句的時候,呼叫row_number() over() 函數

以上兩種方式都可以實現「去重」功能,那兩者之間有何異同呢?接下來,作者將給出詳細的說明。

2 詳解distinct 和 row_number()和over() 的差別

在 SQL 中,關鍵字 詳解distinct 和 row_number()和over() 的差別 用來傳回唯一不同的值。其語法格式為:


SELECT DISTINCT 列名称 FROM 表名称

假設有一個表格“詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別”,包含兩個字段,分別為NAME 和AGE,具體格式如下:

詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別

觀察以上的表,咱們會發現:擁有相同NAME 的記錄有兩條,擁有相同AGE 的記錄有三個。如果咱們執行下面這條SQL 語句,


##

/**
* 其中 PPPRDER 为 Schema 的名字,即表 詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別 在 PPPRDER 中
*/

select 詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別 from PPPRDER.詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別

將會得到以下結果:

詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別##觀察結果,咱們會發現在以上的四筆記錄中,包含兩個NAME 值相同的記錄,即第2 筆記錄和第3 筆記錄的值都為「gavin」。那麼,如果咱們想讓擁有相同 NAME 的記錄只顯示一條該如何實現呢?這時,就需要用到 詳解distinct 和 row_number()和over() 的差別 關鍵字啦!接下來,執行如下SQL 語句,

select 詳解distinct 和 row_number()和over() 的差別 詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別 from PPPRDER.詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別

將會得到以下結果:

##觀察結果,顯然咱們的要求得到實現啦!但是,咱們不禁會想到,如果將 詳解distinct 和 row_number()和over() 的差別 關鍵字同時作用在兩個欄位上將會產生什麼效果呢?既然想到了,咱們就試試唄,運行如下SQL 語句,詳解distinct 和 row_number()和over() 的差別

select 詳解distinct 和 row_number()和over() 的差別 詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別, age from PPPRDER.詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別

得到的結果如下所示:

觀察該結果,哎呀,貌似沒有作用啊?她將全部的記錄都顯示出來了啊!其中 NAME 值相同的記錄有兩條,AGE 值相同的記錄有三條,完全沒有變化啊!但事實上,結果就應該是這樣的。因為詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別andage當詳解distinct 和 row_number()和over() 的差別 作用在多個欄位的時候,她只會將所有欄位值都相同的記錄「去重」掉

,顯然咱們「可憐」的四筆記錄並不滿足該條件,因此詳解distinct 和 row_number()和over() 的差別會認為上面四筆記錄並不相同。空口無憑,接下來,咱們再在表「詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別」中加入一筆完全相同的記錄,驗證一下即可。新增一筆記錄後的表格如下所示:

再執行如下的SQL 語句,詳解distinct 和 row_number()和over() 的差別

select 詳解distinct 和 row_number()和over() 的差別 詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別, age from PPPRDER.詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別

得到的結果如下圖所示:

觀察結果,完美的驗證了咱們上面的結論。 詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別andage

此外,有一點需要大家特別注意,即:

關鍵字詳解distinct 和 row_number()和over() 的差別 只能放在SQL 語句中所有字段的最前面才能起作用,如果放錯位置,SQL 不會報錯,但也不會起到任何效果。

3 row_number() over()

在在SQL Server 資料庫中,為咱們提供了一個函數row_number() 用來給資料庫表中的記錄進行標號,在使用的時候,其後還跟著一個函數over(),而函數over() 的作用是將表中的記錄進行分組

和排序。兩者使用的語法為:

ROW_NUMBER() OVER(PARTITION BY COLUMN1 ORDER BY COLUMN2)

意為:將表格中的記錄按字段COLUMN1分組,按字段COLUMN2 進行排序,其中

# PARTITION BY:表示分組ORDER BY:表示排序

接下来,咱们还用表“詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別”中的数据进行测试。首先,给出没有使用 row_number() over() 詳解distinct 和 row_number()和over() 的差別时查询的结果,如下所示:

詳解distinct 和 row_number()和over() 的差別

然后,运行如下 SQL 语句,


select PPPRDER.詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別.*, row_number() over(partition by age order by 詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別 desc) from PPPRDER.詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別

得到的结果如下所示:

詳解distinct 和 row_number()和over() 的差別

从上面的结果可以看出,其在原表的基础上,多了一列标有数字排序的列。那么反过来分析咱们运行的 SQL 语句,发现其确实按字段 AGE 的值进行分组了,也按字段 NAME 的值进行排序啦!因此,詳解distinct 和 row_number()和over() 的差別的功能得到了验证。

接下来,咱们就研究如何用 row_number() over() 詳解distinct 和 row_number()和over() 的差別实现“去重”的功能。通过观察上面的结果,咱们可以发现,如果以 NAME 分组,以 AGE 排序,然后再取每组的第一个记录或许就可以实现“去重”的功能啊!那么试试看,运行如下 SQL 语句,


/*
* 其中 詳解distinct 和 row_number()和over() 的差別 表示最后添加的那一列
*/

select * from 
(select PPPRDER.詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別.*, row_number() over(partition by 詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別 order by age desc) 詳解distinct 和 row_number()和over() 的差別 from PPPRDER.詳解詳解distinct 和 row_number()和over() 的差別 和 row_number()和over() 的差別)
where 詳解distinct 和 row_number()和over() 的差別 = 1

运行后,得到的结果如下所示:

詳解distinct 和 row_number()和over() 的差別

观察以上的结果,我们发现,哎呀,数据“去重”的功能一不小心就被咱们实现了啊!不过很遗憾,如果咱们细心的话,会发现一个很不爽的事情,那就是在执行以上 SQL 语句进行“去重”的时候,有一条 NAME 值为“gavin”、AGE 值为“18”的记录被过滤掉了,但是在现实生活会中,同名不同年龄的事情太正常了。

4 总结

通过阅读及实践以上内容,咱们已经知道了,无论是用关键字 詳解distinct 和 row_number()和over() 的差別 还是用詳解distinct 和 row_number()和over() 的差別 row_number() over() 都可以实现数据“去重”的功能。但是在实现使用的过程中,咱们要特别注意两者的用法特点以及区别。

在使用关键字 詳解distinct 和 row_number()和over() 的差別 的时候,咱们要知道其作用于单个字段和多个字段的时候是有区别的,作用于单个字段时,其“去重”的是表中所有该字段值重复的数据;作用于多个字段的时候,其“去重”的表中所有字段(即 詳解distinct 和 row_number()和over() 的差別 具体作用的多个字段)值都相同的数据。

使用詳解distinct 和 row_number()和over() 的差別 row_number() over() 的时候,其是按先分组排序后,再取出每组的第一条记录来进行“去重”的(在本篇博文中如此)。当然,在此处咱们还可以通过不同的限制条件来进行“去重”,具体如何实现,就需要大家自己去动脑思考啦!

最后,在本篇博文中,作者详述了自己对用关键字 詳解distinct 和 row_number()和over() 的差別 和詳解distinct 和 row_number()和over() 的差別 row_number() over() 进行数据“去重”的一些认识,希望以上的内容能够对大家有所帮助!

【相关推荐】

1. Mysql免费视频教程

2. 详解innodb_index_stats导入数据时 提示表主键冲突的错误

3. 实例详解 mysql中innodb_autoinc_lock_mode

4. MySQL中添加新用户权限的实例详解

5. 实例详解mysql中init_connect方法

以上是詳解distinct 和 row_number()和over() 的差別的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn