2016-07-26 64 views
1

以下是sql查詢,用於選擇所有導師的姓名,他們的薪水至少超過一位導師(這是留下最少薪酬的導師)。此查詢來自Korth Silberchatz的Database System Concepts。但是我無法想象查詢的使用方式,除此之外,就是這樣做的必要條件。下面的SQL查詢的說明

你可以想像我猜的表。

select distinct T.name 
from instructor as T,instructor as S 
where T.salary > S.salary; 
+0

這是一個交叉連接,請參閱附加鏈接的解釋:http://stackoverflow.com/questions/3538225/how-does-select-from-two-tables-separated-by-a-comma-work-select- from-t1-t2 –

回答

2

書面查詢的另一種方法是......

SELECT DISTINCT 
    T.name 
FROM 
    instructor AS T 
CROSS JOIN 
    instructor AS S 
WHERE 
    T.salary > S.salary 

一般CROSS JOIN s爲一個壞主意。在這裏他們是一個非常糟糕的主意。如果你有100名教師,你可以評估4950個不同的組合,得到一個由99位教師組成的獨特名單。
- Instructor001有支付誰99名指導員少
- Instructor002有98名教練的薪水少誰
- ...
- Instructor100擁有誰的工資少
00指導員 - 總計4950個組合

如果你有1000位教師評估499500組合,以獲得999位教師的唯一列表。

一個更好的想法是......

SELECT 
    i.Name 
FROM 
    instructor i 
WHERE 
    i.salary > (SELECT MIN(salary) FROM instructor) 

或者......

SELECT 
    i.Name 
FROM 
    instructor i 
WHERE 
    i.Name <> (SELECT Name FROM instructor ORDER BY Salary ASC LIMIT 1) 

或者......

SELECT 
    i.* 
FROM 
    instructor i 

EXCEPT 

SELECT 
    i.* 
FROM 
    instructor i 
ORDER BY 
    Salary ASC 
LIMIT 1 

所以,你說得對,這不是必要(或甚至一個好主意)這樣做。

+1

是不是'MIN'? – Blank

+1

@JPG - 呃,我爸爸的愛爾蘭人?這是我能想到的最好的藉口。哎呀,謝謝。 – MatBailie

0

讓我們稍微重構一下這個查詢。

SELECT DISTINCT T.name 
FROM instructor as T 
JOIN instructor as S ON T.salary > S.salary; 

它完全一樣的東西,但它表達不同的語法(並更有效地)。這樣它更具可讀性。

現在,T表是基地表,您查詢。接下來,您加入S別名下的同一個表,以便與其他付費較少的教師(T.salary > S.salary)匹配,這意味着您從T排除了S指導教師不存在的結果行。

在最後你使用DISTINCT關鍵字SELECT條款,爲了不要讓複製T教官其中有一個以上的少支付S教練。

+0

這也是一個非常糟糕的主意。即使有'JOIN',你仍然有笛卡爾產品。 – MatBailie

+0

不,如果你有'工資'字段的索引。當然,還有其他(更好的)方法可以實現相同的結果,但最重要的是解釋查詢邏輯。這只是一個練習。 –

+0

即使有索引,這也是一個笛卡爾積。以100名教練名單,最多支付的教練將與99名其他人員一起參加。那麼第二高的將與98個人加入。依此類推,直到第100個最高位將與0個個體相連。這總共提供了4950個組合。然後*應用「DISTINCT」。 1000名指導員提供499500個組合。等等... – MatBailie