有没有办法在没有子查询的情况下重写这个查询?

时间:2016-11-08 13:10:07

标签: sql sql-server

我从HR模式(oracle)获得了一份员工表。这就是我完成任务的方式(选择部门中薪水最低的员工,如果他们属于他们中的任何一个)

    SELECT D.employee_id,D.Last_name,D.salary,D.department_id
    FROM [HelpDatabase].[dbo].[Employees] D,
         [HelpDatabase].[dbo].[Employees] E
    WHERE D.department_id IS NOT NULL 
      AND E.department_id IS NOT NULL
      AND D.employee_id=E.employee_id
      AND D.salary=ANY (
          SELECT MIN(E.salary) 
          FROM [HelpDatabase].[dbo].[Employees] 
          GROUP BY E.department_id)

查询工作正常,但我已经被告知可以在不使用子查询的情况下进行查询。

3 个答案:

答案 0 :(得分:1)

假设您只是想找到在其部门中薪水最低的员工:

是的,这可以在没有子查询的情况下完成。我们的想法是,您可以查找同一部门中没有其他员工且薪水较低的员工:

select *
from emp
where not exists
(
  select *
  from emp less
  where less.department_id = emp.department_id and less.salary < emp.salary
);

NOT EXISTS查询也可以写为反连接。这是:外部加入较小的收入员工;然后从结果中删除您找到此类人员的所有员工。

select *
from emp
left join emp less on less.department_id = emp.department_id and less.salary < emp.salary
where less.employee_id is null;
但是,你通常不会这样做,因为它是一个技巧,并且它有点模糊了查询实际在做什么。 NOT EXISTS在这里更清楚,要求&#34;给我的员工不存在收入较少的同事#34;

(嗯,在你的情况下,你甚至可以使用其他东西,例如where (department_id, salary) in (select department_id, min(salary) ...)或rank() over partition by department_id order by salary。)

但是,当您的DBMS在not exists查询中证明不足时,反连接是一种解决方案。它们只是写同一件事的另一种方式。

答案 1 :(得分:0)

SELECT D.employee_id,D.Last_name,D.salary,D.department_id
FROM [HelpDatabase].[dbo].[Employees] D,
     (SELECT department_id, MIN(salary) min_salary
      FROM [HelpDatabase].[dbo].[Employees] 
      WHERE department_id is not null
      GROUP BY department_id) E
WHERE D.department_id IS NOT NULL
  AND D.salary=E.min_salary
  AND E.department_id=D.department_id

您可以使用 min(salary)over(partition by department_id)min_salary 来获取min_salary,但它仍会生成子查询,您必须在此之后过滤行

答案 2 :(得分:-1)

SELECT D.employee_id,D.Last_name,MIN(D.salary),D.department_id
    FROM [HelpDatabase].[dbo].[Employees] D
    WHERE D.department_id IS NOT NULL 
     group by D.employee_id,D.Last_name,D.department_id
相关问题