【问题标题】:Find the second highest salary [duplicate]找到第二高的薪水[重复]
【发布时间】:2011-12-20 10:21:19
【问题描述】:

这是一个众所周知的问题。考虑以下

EmployeeID  EmployeeName    Department      Salary   
----------- --------------- --------------- ---------
1           T Cook          Finance         40000.00
2           D Michael       Finance         25000.00
3           A Smith         Finance         25000.00
4           D Adams         Finance         15000.00
5           M Williams      IT              80000.00
6           D Jones         IT              40000.00
7           J Miller        IT              50000.00
8           L Lewis         IT              50000.00
9           A Anderson      Back-Office     25000.00
10          S Martin        Back-Office     15000.00
11          J Garcia        Back-Office     15000.00
12          T Clerk         Back-Office     10000.00

我们需要找出第二高的薪水

With Cte As
(
  Select 
    level
    ,Department
    ,Max(Salary) 
 From plc2_employees
 Where level = 2
 Connect By Prior (Salary) > Salary)
Group By level,Department
)

Select 
    Employeeid
    ,EmployeeName
    ,Department
    ,Salary
From plc2_employees e1
Inner Join Cte e2 On e1.Department = e2.Department
Order By 
    e1.Department
    , e1.Salary desc
    ,e1.EmployeeID

不知何故无法正常工作...我没有得到正确的结果。谁能帮帮我。

【问题讨论】:

  • 您不是对拉里·埃里森感兴趣,而是对甲骨文的其他人感兴趣? (抱歉,我觉得这个主题听起来像......)
  • 是的,这个问题类似于那个问题和其他 SO 问题。我已经看到了。。但我正在尝试使用 Connect by 方法来解决它。原因是我不熟悉它并试图在这种情况下实现它...
  • 你不能使用递归查询来解决这个问题(好吧,你也许可以,但它不是适合这项工作的工具)。您正在运行的具体问题是子句 Connect By Prior (Salary) > Salary 导致每个薪水都加入到它下面的每个薪水。
  • Allan,我正在尝试增强这里提出的第一种方法 (techforum4u.com/entry.php/…).. 请帮助
  • @user1025901:该链接中建议的方法经过深思熟虑。假设您有 1000 名员工:使用此方法您将创建一个包含 499,500 条记录的临时结果集(如果没有相等的记录,不等式连接将创建 n*(n-1)/2 记录),以便找到您要查找的一条记录。这是非常低效的,特别是当有一个已知的解决方案使用更适合该任务的功能(分析查询)时。

标签: sql oracle top-n hierarchical-query


【解决方案1】:

类似

select * from
(
select EmployeeID, EmployeeName, Department, Salary, 
rank () over (partition by Department order by Salary desc) r
from PLC2_Employees
)
where r = 2

编辑 - 对其进行了测试,它给出了您期望的答案。

【讨论】:

  • 好吧,我知道这种方法...即使它也可以使用 Dense_Rank 也可以完成...+ 相关子查询等。我正在尝试一种不同的方法来使用 connect by as 来解决它我是新手……
  • 好的,您最初的问题并不清楚。不确定 connect by 是一个很好的方法。
  • 嗨,格雷格,我基本上是在尝试增强这里提出的第一个解决方案(techforum4u.com/entry.php/…)
【解决方案2】:

如果您要自学如何处理 CONNECT BY,则应首先找到适合该构造的问题。 CONNECT BY 用于处理分层形式的数据,而您的示例不是。薪金之间没有等级关系。试图在错误的问题上强制拟合一个结构是令人沮丧的,而且并不能真正教给你任何东西。

查看演示 HR 模式中的经典员工-经理关系,您可以使用 Oracle 安装。所有员工都向经理报告,包括经理(最高层除外)。然后,您可以使用此架构创建查询以显示例如公司的组织结构图。

【讨论】:

    【解决方案3】:

    START WITH … CONNECT BY 旨在通过探索所有可能的下降路径来探索形成图形的数据。您在START WITH 子句中指定根节点CONNECT BY 子句中指定节点连接(不在WHERE 子句中)

    WHERE 子句过滤器将在 分层条件之后处理,GROUP BYHAVING 相同(当然因为 GROUP BY 是在 WHERE 之后计算的)。

    因此,例如,您必须在这里CONNECT BY PRIOR department = department。还必须避免在有中间工资的情况下,两个工资之间做节点连接。

    因此,最终查询将类似于:

    SELECT level
         , Department
         , Salary
      FROM plc2_employees pe1
     START WITH pe1.salary = (select max(salary) from plc2_employees pe2 WHERE pe2.Department = pe1.Department)
     CONNECT BY PRIOR pe1.Department = pe1.Department
            AND PRIOR pe1.Salary > pe1.Salary
            AND PRIOR pe1.Salary = ( SELECT MIN(Salary) FROM plc2_employees pe3
                                      WHERE pe3.Department = pe1.Department
                                        AND pe3.Salary > pe1.Salary
                                   )
    

    递归条件表明子行和父行之间没有中间工资。

    请注意,这确实是低效的……

    【讨论】:

      【解决方案4】:

      试试这个,它给了第二高的薪水

      select MAX(Salary) as Salary 
      from Employee_salary 
      where Salary not in (select MAX(Salary) from Employee_salary) 
      

      【讨论】:

        【解决方案5】:

        你可以使用这个查询:

        select * from 
        employee e1 
        where 2 = (select count (distinct (salary)) 
        from employee e2 
        where e2.salary >=e1.salary);
        

        【讨论】:

          【解决方案6】:

          从以salary为列的employee表中找出第二高的薪水: 数据库:DB2

          with t as
          (
          select distinct salary from employee order by salary desc
          ),
          tr as 
          (
          select salary, row_Number() over() r from t 
          )
          select salary from tr where r = 2
          

          【讨论】:

            【解决方案7】:

            试试这个, 它给了第二高的薪水......

            select MAX(Salary) as Salary 
            from Employee_salary 
            where Salary not in (select MAX(Salary) from Employee_salary )
            

            如果你想找到第 n 高的薪水,你可以使用以下查询.... 你只需要做一个改变...... 把 N=n 的值放最高

            干杯....:)

            SELECT * FROM Employee_salary Emp1 
            WHERE (N-1) = (SELECT COUNT(DISTINCT(Emp2.Salary)) 
                           FROM Employee_salary Emp2 
                           WHERE Emp2.Salary > Emp1.Salary)
            

            【讨论】:

            • 试试这个,它的测试:)
            【解决方案8】:

            这会起作用 -

            SELECT MIN(Salary) 
            FROM employee 
            WHERE salary IN (SELECT TOP 2 salary FROM employee ORDER BY salary DESC)
            

            【讨论】:

              【解决方案9】:

              首先,按降序(从大到小)选择不同的薪水,从该集合中选择前 2 个并按升序排列(将数字 2 放在顶部),然后从这两个中选择前 1 个:

              select top 1 s.Salary
                from 
                 (select top 2 t.Salary
                    from
                        (select distinct Salary
                           from PLC2_Employees
                          order by Salary desc) t
                   order by Salary asc) s
              

              【讨论】:

              • Oracle 不支持TOP
              • 是的,这是真的(Orcle 不支持 top,我们可以使用 Row_Number() 或 RowNum).. 而且这个查询也不会处理关系(如果在 sql server 或其他 rdbms 中运行支持TOP)希望
              猜你喜欢
              • 2019-04-17
              • 1970-01-01
              • 2011-01-30
              • 1970-01-01
              • 2020-01-29
              • 1970-01-01
              • 1970-01-01
              • 2019-05-04
              • 1970-01-01
              相关资源
              最近更新 更多