【问题标题】:How to get second-highest salary employees in a table如何在一个表中获得第二高薪的员工
【发布时间】:2011-11-17 01:27:04
【问题描述】:

这是我今天下午收到的一个问题:

SQL Server 中有一个包含 ID、Name 和 Salary of Employees 的表,获取薪水第二高的员工的姓名

这是我的答案,我只是写在纸上,不确定它是否完全有效,但它似乎有效:

SELECT Name FROM Employees WHERE Salary = 
( SELECT DISTINCT TOP (1) Salary FROM Employees WHERE Salary NOT IN
 (SELECT DISTINCT TOP (1) Salary FROM Employees ORDER BY Salary DESCENDING)
ORDER BY Salary DESCENDING)

我认为这很丑,但这是我想到的唯一解决方案。

你能给我推荐一个更好的查询吗?

非常感谢。

【问题讨论】:

    标签: sql sql-server tsql optimization


    【解决方案1】:

    试试这个简单的方法

    select name,salary from employee where salary =
    (select max(salary) from employee where salary < (select max(salary) from employee ))
    

    【讨论】:

    【解决方案2】:
    SELECT `salary` AS emp_sal, `name` , `id`
    FROM `employee`
    GROUP BY `salary` ORDER BY `salary` DESC
    LIMIT 1 , 1 
    

    【讨论】:

      【解决方案3】:

      要获取您可以使用的具有第二高不同工资金额的员工的姓名。

      ;WITH T AS
      (
      SELECT *,
             DENSE_RANK() OVER (ORDER BY Salary Desc) AS Rnk
      FROM Employees
      )
      SELECT Name
      FROM T
      WHERE Rnk=2;
      

      如果将 Salary 编入索引,则以下内容可能会更有效,但尤其是在有很多员工的情况下。

      SELECT Name
      FROM   Employees
      WHERE  Salary = (SELECT MIN(Salary)
                       FROM   (SELECT DISTINCT TOP (2) Salary
                               FROM   Employees
                               ORDER  BY Salary DESC) T);
      

      测试脚本

      CREATE TABLE Employees
        (
           Name   VARCHAR(50),
           Salary FLOAT
        )
      
      INSERT INTO Employees
      SELECT TOP 1000000 s1.name,
                         abs(checksum(newid()))
      FROM   sysobjects s1,
             sysobjects s2
      
      CREATE NONCLUSTERED INDEX ix
        ON Employees(Salary)
      
      SELECT Name
      FROM   Employees
      WHERE  Salary = (SELECT MIN(Salary)
                       FROM   (SELECT DISTINCT TOP (2) Salary
                               FROM   Employees
                               ORDER  BY Salary DESC) T);
      
      WITH T
           AS (SELECT *,
                      DENSE_RANK() OVER (ORDER BY Salary DESC) AS Rnk
               FROM   Employees)
      SELECT Name
      FROM   T
      WHERE  Rnk = 2;
      
      SELECT Name
      FROM   Employees
      WHERE  Salary = (SELECT DISTINCT TOP (1) Salary
                       FROM   Employees
                       WHERE  Salary NOT IN (SELECT DISTINCT TOP (1) Salary
                                             FROM   Employees
                                             ORDER  BY Salary DESC)
                       ORDER  BY Salary DESC)
      
      SELECT Name
      FROM   Employees
      WHERE  Salary = (SELECT TOP 1 Salary
                       FROM   (SELECT TOP 2 Salary
                               FROM   Employees
                               ORDER  BY Salary DESC) sel
                       ORDER  BY Salary ASC)  
      

      【讨论】:

        【解决方案4】:

        创建临时表

        Create Table #Employee (Id int identity(1,1), Name varchar(500), Salary int)
        

        插入数据

        Insert Into #Employee
            Select 'Abul', 5000
        Union ALL 
            Select 'Babul', 6000
        Union ALL 
            Select 'Kabul', 7000
        Union ALL 
            Select 'Ibul', 8000
        Union ALL 
            Select 'Dabul', 9000
        

        查询将是

        select top 1 * from #Employee a
        Where a.id <> (Select top 1 b.id from #Employee b ORDER BY b.Salary desc)
        order by a.Salary desc
        

        删除表

        drop table #Empoyee
        

        【讨论】:

          【解决方案5】:
           - Method 1
          
              select max(salary) from Employees
                  where salary< (select max(salary) from Employees)
          
          
          
           - Method 2
          
           select MAX(salary) from Employees 
              where salary not in(select MAX(salary) from Employees)
          
          
          
           - Method 3
          
          select MAX(salary) from Employees 
              where salary!= (select MAX(salary) from Employees )
          

          【讨论】:

            【解决方案6】:

            试试这个:

             WITH CTE AS
             (
             SELECT DENSE_RANK() OVER (ORDER BY SALARY DESC)RN,* FROM Users
             )
             SELECT * FROM CTE WHERE RN=2
            

            【讨论】:

              【解决方案7】:

              使用此 SQL,员工姓名将获得第二高的薪水

              Select top 1 start at 2 salary from employee group by salary order by salary desc;
              

              【讨论】:

                【解决方案8】:

                如果您想显示获得第二高薪水的员工的姓名,请使用:

                SELECT employee_name 
                FROM employee
                WHERE salary = (SELECT max(salary) 
                                FROM employee
                                WHERE salary < (SELECT max(salary) 
                                                FROM employee);
                

                【讨论】:

                  【解决方案9】:
                  SELECT MAX(Salary) FROM Employee
                  WHERE Salary NOT IN (SELECT MAX(Salary) FROM Employee)
                  

                  【讨论】:

                    【解决方案10】:
                    declare
                    
                    cntr number :=0;
                    
                    cursor c1 is
                    
                    select salary from employees order by salary desc;
                    
                    z c1%rowtype;
                    
                    begin
                    
                    open c1;
                    
                    fetch c1 into z;
                    
                    while (c1%found) and (cntr <= 1) loop
                    
                    
                    cntr := cntr + 1;
                    
                    fetch c1 into z;
                    
                    dbms_output.put_line(z.salary);
                    
                    end loop;
                    
                    end;
                    

                    【讨论】:

                      【解决方案11】:
                      select MAX(Salary) from Employee WHERE Salary NOT IN (select MAX(Salary) from Employee );
                      

                      【讨论】:

                        【解决方案12】:

                        我想在这里发布可能是最简单的解决方案。它在mysql中工作。

                        请在你的最后检查一下:

                        SELECT name
                        FROM `emp`
                        WHERE salary = (
                        SELECT salary
                        FROM emp e
                        ORDER BY salary DESC
                        LIMIT 1
                        OFFSET 1 
                        

                        【讨论】:

                          【解决方案13】:
                          select max(sal) , Department no. from employee where sal<max(sal)
                          

                          【讨论】:

                            【解决方案14】:

                            这是一个简单的方法:

                            select name
                            from employee
                            where salary=(select max(salary)
                                          from(select salary from employee
                                               minus
                                               select max(salary) from employee));
                            

                            【讨论】:

                              【解决方案15】:
                              SELECT name
                              FROM employee
                              WHERE salary =
                              (SELECT MIN(salary) 
                                FROM (SELECT TOP (2) salary
                                FROM employee
                                ORDER BY salary DESC) )
                              

                              【讨论】:

                                【解决方案16】:

                                试试这个:无论行数如何,这都会给出动态结果

                                SELECT * FROM emp WHERE salary = (SELECT max(e1.salary) 
                                FROM emp e1 WHERE e1.salary < (SELECT Max(e2.salary) FROM emp e2))**
                                

                                【讨论】:

                                  【解决方案17】:

                                  这是一个简单的查询。如果你想要第二个最小值,那么只需将最大值更改为最小值并将小于()。

                                      select max(column_name) from table_name where column_name<(select max(column_name) from table_name)
                                  

                                  【讨论】:

                                    【解决方案18】:

                                    另一种直观的方法是:- 假设我们想找到第 N 高的薪水然后

                                    1) 按工资降序对员工进行排序

                                    2) 使用 rownum 获取前 N 条记录。所以在这一步中,这里的第 N 条记录是第 N 高的薪水

                                    3) 现在按升序对这个临时结果进行排序。因此,第 N 高的薪水现在是第一个记录

                                    4) 从此临时结果中获取第一条记录。

                                    这将是第 N 高的薪水。

                                    select * from 
                                     (select * from 
                                       (select * from  
                                           (select * from emp order by sal desc)  
                                       where rownum<=:N )  
                                     order by sal )
                                    where rownum=1;
                                    

                                    如果有重复的薪水,那么在最里面的查询中可以使用 distinct。

                                    select * from 
                                     (select * from 
                                       (select * from  
                                           (select distinct(sal) from emp order by 1 desc)  
                                       where rownum<=:N )  
                                     order by sal )
                                    where rownum=1;
                                    

                                    【讨论】:

                                      【解决方案19】:
                                      SELECT * 
                                      FROM TABLE1 AS A 
                                      WHERE NTH HIGHEST NO.(SELECT COUNT(ATTRIBUTE) FROM TABLE1 AS B) WHERE B.ATTRIBUTE=A.ATTRIBUTE;
                                      

                                      【讨论】:

                                        【解决方案20】:

                                        无需使用任何特定于 Oracle、MySQL 等的特殊功能的简单方法。

                                        假设 EMPLOYEE 表有如下数据。工资可以重复。

                                        通过人工分析,我们可以确定排名如下:-

                                        查询也可以得到同样的结果

                                        select  *
                                        from  (
                                        select tout.sal, id, (select count(*) +1 from (select distinct(sal) distsal from     
                                        EMPLOYEE ) where  distsal >tout.sal)  as rank  from EMPLOYEE tout
                                        ) result
                                        order by rank
                                        

                                        首先我们找出不同的薪水。 然后我们找出大于每一行的不同薪水的计数。 这不过是那个id的等级。 对于最高薪水,此计数为零。所以“+1”是从 1 开始排名。

                                        现在我们可以通过在上面的查询中添加 where 子句来获得第 N 级的 ID。

                                        select  *
                                        from  (
                                        select tout.sal, id, (select count(*) +1 from (select distinct(sal) distsal from     
                                        EMPLOYEE ) where  distsal >tout.sal)  as rank  from EMPLOYEE tout
                                        ) result
                                        where rank = N;
                                        

                                        【讨论】:

                                          【解决方案21】:

                                          下面的查询可用于查找第n个最大值,只需将第n个数字中的2替换为2

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

                                          【讨论】:

                                            【解决方案22】:

                                            我认为这可能是最简单的。

                                            SELECT Name FROM Employees group BY Salary DESCENDING limit 2;
                                            

                                            【讨论】:

                                            • 注意问题中的标签; SQL Server 不支持LIMIT
                                            【解决方案23】:

                                            我们也可以使用

                                            select e2.max(sal), e2.name
                                            from emp e2
                                            where (e2.sal <(Select max (Salary) from empo el))
                                            group by e2.name
                                            

                                            请告诉我这种方法有什么问题

                                            【讨论】:

                                            • 它将返回所有工资低于最高工资的员工,而不仅仅是第二高的员工
                                            • 这一行: where (e2.sal
                                            【解决方案24】:
                                            select max(age) from yd where age<(select max(age) from HK) ; /// True two table Highest 
                                            
                                            SELECT * FROM HK E1 WHERE 1 =(SELECT COUNT(DISTINCT age) FROM HK E2 WHERE E1.age < E2.age); ///Second Hightest age RT single table 
                                            
                                            select age from hk e1 where (3-1) = (select count(distinct (e2.age)) from yd e2 where e2.age>e1.age);//// same True Second Hight age RT two table
                                            
                                            select max(age) from YD where age not in (select max(age) from YD);  //second hight age in single table 
                                            

                                            【讨论】:

                                            • 您能否在您的帖子中添加一些解释(不仅仅是代码)?
                                            【解决方案25】:

                                            我想你会想使用DENSE_RANK,因为你不知道有多少员工有相同的薪水,而且你确实说过你想要员工的姓名。

                                            CREATE TABLE #Test
                                            (
                                                Id INT,
                                                Name NVARCHAR(12),
                                                Salary MONEY
                                            )
                                            
                                            SELECT x.Name, x.Salary
                                            FROM
                                                    (
                                                    SELECT  Name, Salary, DENSE_RANK() OVER (ORDER BY Salary DESC) as Rnk
                                                    FROM    #Test
                                                    ) x
                                            WHERE x.Rnk = 2
                                            

                                            ROW_NUMBER 会给你唯一的编号,即使薪水并列,如果你有多个人并列最高薪水,简单的RANK 不会给你一个“2”作为排名。我已经更正了这一点,因为 DENSE_RANK 在这方面做得最好。

                                            【讨论】:

                                              【解决方案26】:
                                              select * from emp where salary = ( select salary from (select ROW_NUMBER() over (order by salary) as 'rownum', * from emp) t -- Order employees according to salary where rownum = 2 -- Get the second highest salary )

                                              【讨论】:

                                                【解决方案27】:

                                                CTE 怎么样?

                                                ;WITH Salaries AS
                                                (
                                                    SELECT Name, Salary,
                                                       DENSE_RANK() OVER(ORDER BY Salary DESC) AS 'SalaryRank'
                                                    FROM 
                                                        dbo.Employees
                                                )
                                                SELECT Name, Salary
                                                FROM Salaries  
                                                WHERE SalaryRank = 2
                                                

                                                DENSE_RANK() 将为您提供所有薪水第二高的员工 - 无论有多少员工拥有(相同的)最高薪水。

                                                【讨论】:

                                                  猜你喜欢
                                                  • 2014-09-02
                                                  • 2011-01-30
                                                  • 1970-01-01
                                                  • 1970-01-01
                                                  • 1970-01-01
                                                  • 1970-01-01
                                                  • 1970-01-01
                                                  • 1970-01-01
                                                  • 1970-01-01
                                                  相关资源
                                                  最近更新 更多