如何用SQL實現組內前幾名的輸出


關於問題

如何查詢組內最大的,最小的,大家或許都知道,無非是min、max的函數使用。可是如何在MySQL中查找組內最好的前兩個,或者前三個?

什么是相關子查詢

在提出對於這個問題的對應方法之前,首先來理解一個概念:相關子查詢。

所謂相關子查詢,就是其查詢的執行依賴於外部查詢。多數情況下是子查詢的where子句中引用了外部查詢的表。執行過程:
  • 從外層查詢中取出一個元組,將元組相關列的值傳給內層查詢
  • 執行內層查詢,得到子查詢操作的值
  • 外查詢根據子查詢返回的結果或結果集得到滿足條件的行
  • 然后外層查詢取出下一個元組重復做步驟1-3,直到外層的元組全部處理完畢。

下面會結合例子,在說明組內取值的同時,是如何使用相關子查詢的。

在MySQL中查詢每組中的前N個值

有如上的表,我們需要找出每個類型(type)中最便宜的前兩種水果,我們可以采取這樣的方法:
select type, variety, price 
from fruits
where (
   select count(*) from fruits as f
   where f.type = fruits.type and f.price < fruits.price
) <= 1;

這個查詢語句就使用到了相關子查詢,結合之前我們提到的相關子查詢的查詢步驟,我們來解析一下這個SQL語句。

從表中首先取出第一條數據,type為apple,variety為gala,price為2.79。相關子查詢中,會將元組相關列的值傳給內層查詢,在子查詢中我們看到
select count(*) from fruits as f
where f.type = fruits.type and f.price < fruits.price

也就是說,實際上這條語句此時應該是這樣
select count(*) from fruits as f
where f.type = apple and f.price < 2.79
即,在apple這個類別中,價格比2.79還要低的元組的數量。

我們再看全貌
select type, variety, price
from fruits
where (
   select count(*) from fruits as f
   where f.type = apple and f.price < 2.79
) <= 1;
可以知道,apple中價格低於2.79的只有fuji這個元組,即值為1,滿足子條件<=1的條件,所以該元組會被輸出。

如果不好理解,這樣來看。其實這個子條件的意思就是在說, 我提取一個元組A,如果這個元組A所屬的類別中,價格比元組A低的最多只有一個,那么就輸出(即它本身是最便宜的,那么比它價格還低的就只有0個;或者它是第二便宜的,那么價格比它低的就只有1個。這樣一來,只要數量條件為<=1,那么就得到了最便宜的兩種水果)

按照相關子查詢的執行順序,第一個元組符合條件,被輸出。接下來,把第二個元組的值帶入,如果符合條件則輸出,接着第三個元組第四個元組... 直到所有的元組帶入篩選完畢,整個查詢過程也就結束了。

什么,你說價格排列沒有順序?加上order就可以了。
select type, variety, price
from fruits
where (
   select count(*) from fruits as f
   where f.type = fruits.type and f.price < fruits.price
) <= 1
order by fruits.type, fruits.price
 

參考鏈接




免責聲明!

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



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