IN语句转换

时间:2017-04-09 00:49:06

标签: sql sql-server

使用子查询列出所有男性员工的薪水高于任何女性员工。这看起来不错吗?我还需要将其更改为IN语句。我尝试的一切都归功于所有女性工资。

SELECT FirstName, LastName, Salary
FROM Employee
WHERE Salary > ALL
(Select Salary FROM Employee
WHERE Gender = 'F')

2 个答案:

答案 0 :(得分:0)

首先,我将其写为:

SELECT m.*
FROM Employee m
WHERE m.Gender = 'M' AND
      m.Salary > (SELECT MAX(f.Salary)
                  FROM Employee f
                  WHERE f.Gender = 'F'
                 );

我喜欢这个版本,因为它很明确。它几乎直接翻译为“让所有男性获得的收入超过收入最高的女性。”

您的版本也可以,假设gender只占用两个值。但是,它依赖于细微之处:比较是>。所以,没有女性的薪水高于所有女性(包括她自己)。因此,外部查询只能返回非女性,这恰好是男性。

= 'M'的条件不再通过那些心理体操,而是使查询的意图更加清晰。

使用该条件,查询更清晰:

SELECT m.*
FROM Employee m
WHERE m.Gender = 'M' AND
      m.Salary > ALL (SELECT f.Salary
                      FROM Employee f
                      WHERE f.Gender = 'F'
                     );

我应该注意,在一个边缘情况下,此版本优于具有MAX()的版本。如果没有女性,这将返回所有员工。 MAX()版本将不会返回任何行。

我应该补充一点:如何将此查询转换为使用IN的版本并不明显,至少以合理的方式。

答案 1 :(得分:0)

是的,记录中,我认为戈登的答案在技术上要比后面的好得多。他做得对。使用IN的要求坦率地说是奇怪的。

由于x > ALL y自然转换为NOT EXISTS y such that x <= y 并且EXISTS可以相对自然地转换为IN,我们可以x NOT IN (z such that z <= y)执行此操作。假设Employee表有一个名为EmployeeID的PK字段,您可以按照以下方式执行此操作(我为您免费提供了一些奖励IN):

SELECT 
    m.FirstName,
    m.LastName,
    m.Salary
FROM
    Employee m
WHERE
    m.Gender IN ('M')
    AND m.Salary is not null
    AND m.EmployeeID NOT IN
    (
     select m2.EmployeeID
     from Employee m2
     where m2.Salary <= (select f.Salary 
                         FROM Employee f
                         where f.Gender IN ('F'))
    )
    AND 'Why' IN ('Why','IN','Why','?')
    AND 'Why' NOT IN ('Another','Way','?')

这比戈登的答案更可怕而且效率低得多。

如果这是课程作业的一部分,那么我不得不想知道这个作业的人在想什么。很明显他们根本不知道他们在做什么,但也许他们希望你跳过一些合乎逻辑的箍或者教你通常可以用多种不同的方式实现同​​样的事情,这些可能或者可能效率不高。