日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

sql如何先排序再去重

發布時間:2023/12/18 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sql如何先排序再去重 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

場景

有一張得分表(score),記錄了用戶每次的得分,同一個人可能有多個得分。

idnamescore
1tom45
2jack78
3tom34
...

需求:找出分數最高的前5個人。

SQL1

首先我們寫個最簡單的sql:

select id, name, score from score order by score desc limit 5;

如果sql這樣寫,結果可能是:

idnamescore
2jack78
1tom45
3tom34

排序了,但是沒有去重

SQL2

那么我們加上去重:

select distinct name from score order by score desc limit 5;

首先第一點是這個sql未必能執行。在一些數據庫版本,這個sql可以被執行,在一些版本則會提示你order by的字段必須在distinct中存在(見SQL3)。

但是即使能執行,這個sql也得不到預期結果。原因是distinct優先于order by 被數據庫執行。

在執行distinct name的時候,如上文中的數據。是取id=1的數據,還是id=3的數據呢?其實這是數據庫自行決定的。因此,可能會不正確選擇數據。

比如真的執行這個sql,可能去重的結果是:

idnamescore
2jack78
3tom34

然后再執行一個order by,就會認為第一名是jack78分,第二名是tom34分。然而其實tom應該是45分,這個45分就在數據庫執行distinct的時候被錯誤的丟棄了,畢竟先執行distinct的時候不知道你到底要哪個數據。

SQL3

那么我們把score加入select中呢?

select distinct name, score from score order by score desc limit 5;

很明顯,這樣寫的執行結果和我們預期不符。因為如果寫:distinct name,score實際上是對name和score一起去重。比如name都是jack,score都是45。那么這行就會被去掉。

但是問題是正因為把score當做去重的條件了。所以對于同名的人,比如都叫tom,會因為其有兩個分數,導致不能被去重,從而保留兩行記錄。結果就是好像沒有去重。

SQL4

那我不用distinct,用group by進行去重可以嗎?

select name from score group byname order by score desc limit 5;

也不行,因為在group by的時候,數據庫還是不知道對兩行name一樣的數據,究竟應該留下哪一行。

SQL5

正確的寫法:

select name from score group byname order by max(score) desc limit 5;

這樣寫,在執行group by的時候,數據庫就知道要保留score最大的那一行了。

轉載于:https://www.cnblogs.com/dsj2016/p/10679366.html

總結

以上是生活随笔為你收集整理的sql如何先排序再去重的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。