【问题标题】:Get employees which have smaller salary than any of those who sold more than one order获得薪水低于任何销售超过一个订单的员工的员工
【发布时间】:2020-03-31 14:19:58
【问题描述】:

抱歉,标题太长,但我想解释一下情况。

我的大脑快要爆炸了我已经尝试了五个小时,但我不明白。头疼得厉害。

我希望找到那些薪水低于任何已售出一个或多个订单的员工。有两个表EMPLOYEESORDERS

EMPLOYEES 有这些列;名字、姓氏、社会安全号码、薪水。

ORDERS 有这些列;社会保险号、订单号

这是迄今为止最好的解决方案。

SELECT H.SOCSECNUM, H.LASTNAME, H.FIRSTNAME, H.SALARY
FROM EMPLOYEES H
WHERE H.SALARY < ALL(SELECT COUNT(T.ORDERID)
                     FROM ORDERS T
                     WHERE  H.SOCSECNUM = T.SOCSECNUM
                     HAVING COUNT(T.ORDERID) > 0
                     );

我理解这就像获取所有员工的社会保险号、姓名和薪水,这些员工的薪水低于任何销售超过 0 个订单的员工。

我是傻还是这有什么问题?现在这会打印所有有 0 个订单的员工。如果我更改 0 -> 1,它会打印所有拥有一个或更少订单的员工。

【问题讨论】:

  • 在我看来,您是在将薪水与订单 ID 的数量进行比较。
  • 请用您正在使用的数据库标记您的问题。
  • orders表会不会只有下单的ssn?

标签: sql join select group-by


【解决方案1】:

我认为这就是您要编写的查询:

select e.*
from employees e
where h.salary < all (
    select h1.salary
    from employees e1
    where exists (select 1 from orders o1 where o1.socsecnum = e1.socsecnum)
)

子查询返回至少完成一次销售的员工的工资列表。然后,您可以使用 all 来过滤表格。

你也可以使用聚合:

select e.*
from employees e
where h.salary < (
    select min(h1.salary)
    from employees e1
    where exists (select 1 from orders o1 where o1.socsecnum = e1.socsecnum)
)

【讨论】:

    【解决方案2】:

    您需要员工的订单数量和工资。这在一行中很有帮助。所以,使用JOIN:

    select e.*, numorders
    from employees e left join
         (select o.socseqnum, count(*) as numorders
          from orders o
          group by o.socseqnum
         ) o
         on e.socseqnum = o.socseqnum;
    

    然后,我将使用窗口函数来获取单订单员工的最低工资并与之进行比较:

    select eo.*
    from (select e.*, o.numorders,
                 min(case when numorders = 1 then e.salary end) over () as min_salary_1order
          from employees e left join
               (select o.socseqnum, count(*) as numorders
                from orders o
                group by o.socseqnum
               ) o
               on e.socseqnum = o.socseqnum
         ) eo
    where salary < min_salary_1order
    

    【讨论】:

      【解决方案3】:

      使用uncorrelated subquery

      select *
      from employees 
      where salary < (select min(salary) 
                      from employees 
                      where socsecnum in (select socsecnum  
                                          from orders 
                                          where socsecnum  is not null));
      

      【讨论】:

        猜你喜欢
        • 2019-08-21
        • 1970-01-01
        • 1970-01-01
        • 2018-09-07
        • 1970-01-01
        • 1970-01-01
        • 2011-11-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多