2016-07-26 70 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