2015-01-16 44 views
2

我已經where子句中的MySQL「其中3」

SELECT DISTINCT salary 
FROM salary e1 
WHERE 3 = (
SELECT count(DISTINCT salary) 
FROM salary e2 
WHERE e1.salary >= e2.salary) 

它工作正常,但我想知道,爲什麼我們把條件「凡3」從我的表在這裏我的查詢取3薪水最高?它如何表現?

+1

它正在測試計數(*)子查詢是否返回3,就這些了。 –

+0

其實有更好的方法來做到這一點。 – Sirko

回答

2

相等比較比較兩個值。一邊是常數值3,另一邊是子查詢返回的值。

如果比較的結果對於正在評估的行爲TRUE,則將返回該行。否則,該行將不會被返回。

這裏的「技巧」是右側的子查詢。這就是我們所說的「相關」子查詢。對於正在評估的每一行都會運行。

基本上,操作上可以這樣描述...

訪問一行從salary表,並從它那裏得到的salary列的值。

運行另一個查詢,使用值salary列來獲得計數。

相比之下,數到3

如果比較的結果爲true,返回該行的恆定值,否則將其丟棄。

訪問salary表中的下一行並獲取工資值。

運行另一個查詢,使用我們剛剛獲得的值來計算。

比較計數至3。

如果比較的結果爲true,返回該行的恆定值,否則丟棄。

只需重複說明,直到我們完成了salary表中的所有行。

最後一步是DISTINCT操作,它消除了任何我們將返回的重複項。

這就是它的表現。


就性能而言,在大型設備上,相關的子查詢將分別用於我們的午餐和我們的午餐盒。這不是唯一可以返回此結果的查詢模式,還有其他查詢將返回相同結果的工作量更少。

+0

感謝調試它..我得到了它是如何工作:) –

3

你的查詢很慢,不是因爲那個3,而是因爲它在內部查詢中不必要地使用。 @ spencer7593提供的The answer解釋了它是如何工作的,你可以看到它一次又一次地做同樣的事情。

查詢可以寫成這樣簡單:

SELECT DISTINCT e1.salary 
FROM salary e1 
ORDER BY e1.salary DESC 
LIMIT 3; 

注:

不需要別名e1但我讓它的FORM子句中和ORDER BY子句中使用它以明確什麼代表salary的每個實例(表和字段都有這個名稱)。

它是如何工作的:
ORDER期從表「工資」 BYsalary降行(第一最大的工資),SELECT唯一DISTINCT值(這是你寫的很好)和LIMIT S中結果集設置爲3行。

實際上,它在從列salary找到3個最大不同值後停止執行。

如果表上有一個salary字段的索引,它就像風一樣運行。如果它沒有這樣的索引,現在創建它:

ALTER TABLE `salary` ADD INDEX (`salary`);