亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

SQL僅選擇列上具有最大值的行[duplicate]

SQL僅選擇列上具有最大值的行[duplicate]

慕少森 2019-05-20 17:28:33
我有這個文件表(這里是簡化版):+------+-------+--------------------------------------+| id   | rev   | content                              |+------+-------+--------------------------------------+| 1    | 1     | ...                                  || 2    | 1     | ...                                  || 1    | 2     | ...                                  || 1    | 3     | ...                                  |+------+-------+--------------------------------------+如何為每個id選擇一行并且只選擇最大轉速?使用上面的數據,結果應該包含兩行:[1, 3, ...]和[2, 1, ..]。我正在使用MySQL。目前,我在while循環中使用檢查來檢測并覆蓋結果集中的舊轉速。但這是實現結果的唯一方法嗎?是不是有SQL解決方案?
查看完整描述

4 回答

?
牧羊人nacy

TA貢獻1862條經驗 獲得超7個贊

乍一看...

您只需要一個GROUP BY具有MAX聚合函數的子句:

SELECT id, MAX(rev)FROM YourTableGROUP BY id

從來沒有這么簡單,是嗎?

我剛剛注意到你也需要這個content專欄。

這是SQL中一個非常常見的問題:在每個組標識符的列中查找具有一些最大值的行的整個數據。在我的職業生涯中,我聽到了很多。實際上,這是我在當前工作的技術面試中回答的問題之一。

實際上,StackOverflow社區創建一個標記只是為了處理這樣的問題:每個組中最大的n。

基本上,您有兩種方法可以解決該問題:

加入簡單的group-identifier, max-value-in-group子查詢

在這種方法中,您首先group-identifier, max-value-in-group在子查詢中找到(上面已經解決過)。然后將表連接到子查詢,group-identifier并且兩者都相等max-value-in-group

SELECT a.id, a.rev, a.contentsFROM YourTable aINNER JOIN (
    SELECT id, MAX(rev) rev    FROM YourTable    GROUP BY id) b ON a.id = b.id AND a.rev = b.rev

Left加入self,調整連接條件和過濾器

在這種方法中,你自己加入了表。當然,平等在于group-identifier。然后,2個聰明的舉動:

  1. 第二個連接條件是左側值小于右側值

  2. 當你執行第1步時,實際具有最大值的行將NULL在右側(它是a LEFT JOIN,記住嗎?)。然后,我們過濾連接結果,僅顯示右側所在的行NULL。

所以你最終得到:

SELECT a.*FROM YourTable aLEFT OUTER JOIN YourTable b    ON a.id = b.id AND a.rev < b.revWHERE b.id IS NULL;

結論

兩種方法都帶來了完全相同的結果。

如果有兩行max-value-in-groupfor group-identifier,則兩行都將在結果中。

這兩種方法都是SQL ANSI兼容的,因此,無論其“風味”如何,它都可以與您喜歡的RDBMS一起使用。

這兩種方法都具有性能友好性,但您的里程可能會有所不同(RDBMS,DB結構,索引等)。所以,當你選擇一種方法而不是另一種方法時,基準。并確保你選擇對你最有意義的一個。


查看完整回答
反對 回復 2019-05-20
?
拉丁的傳說

TA貢獻1789條經驗 獲得超8個贊

我的偏好是使用盡可能少的代碼......


你可以IN 嘗試這樣做:


SELECT * 

FROM t1 WHERE (id,rev) IN 

( SELECT id, MAX(rev)

  FROM t1

  GROUP BY id

)

在我看來它不那么復雜......更容易閱讀和維護。


查看完整回答
反對 回復 2019-05-20
?
慕的地10843

TA貢獻1785條經驗 獲得超8個贊

我很驚訝,沒有答案提供SQL窗口功能解決方案:

SELECT a.id, a.rev, a.contents  FROM (SELECT id, rev, contents,
               ROW_NUMBER() OVER (PARTITION BY id ORDER BY rev DESC) rank          FROM YourTable) a WHERE a.rank = 1

在SQL標準ANSI / ISO標準SQL:2003中添加,后來使用ANSI / ISO標準SQL:2008進行了擴展,現在所有主要供應商都可以使用窗口(或窗口)功能。有更多類型的排名函數可用于處理平局問題:RANK, DENSE_RANK, PERSENT_RANK


查看完整回答
反對 回復 2019-05-20
  • 4 回答
  • 0 關注
  • 820 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號