【问题标题】:how to retrieve highest and lowest salary from following table?如何从下表中检索最高和最低工资?
【发布时间】:2015-10-21 10:31:19
【问题描述】:

我有员工表

 EMP_ID | F_NAME    | L_NAME  | SALARY | JOINING_DATE                 | DEPARTMENT
-----------------------------------------------------------------------------------
 101    | John      | Abraham | 100000 | 01-JAN-14 09.15.00.000000 AM | Banking
 102    | Michel    | Clarke  | 800000 |                              | Insaurance
 102    | Roy       | Thomas  | 70000  | 01-FEB-13 12.30.00.000000 PM | Banking
 103    | Tom       | Jose    | 600000 | 03-FEB-14 01.30.00.000000 AM | Insaurance
 105    | Jerry     | Pinto   | 650000 | 01-FEB-13 12.00.00.000000 PM | Services
 106    | Philip    | Mathew  | 750000 | 01-JAN-13 02.00.00.000000 AM | Services
 107    | TestName1 | 123     | 650000 | 01-JAN-13 12.05.00.000000 PM | Services
 108    | TestName2 | Lname%  | 600000 | 01-JAN-13 12.00.00.000000 PM | Insaurance

我想在 oracle sql 中从上表中找到最高和最低薪水。 如果我这样做了

 select max(salary) from (select * from (select salary from employee) where   rownum <2);

它返回MAX(SALARY) = 100000 它应该返回800000

如果我这样做

select max(salary)
  from (select * from (select salary from employee) 
         where rownum <3);

它返回MAX(SALARY) = 800000

如果我这样做

select min(salary)
  from (select * from(select salary from employee)
         where rownum < 2);

它将返回MIN(SALARY) = 100000,它应该返回70000

这个查询有什么问题?

正确的查询应该是什么?

【问题讨论】:

  • 工资列的数据类型是什么?你需要to_number()吗?
  • 旁注:使用没有order by 子句的rownum 过滤器通常是一个错误。
  • ROWNUM 不会确保返回的行的顺序。它只是一个伪列,在返回行后分配。如果没有ORDER BY,则无法保证顺序并且随机返回行。见stackoverflow.com/a/30321788/3989608
  • 如果他们帮助了你,你应该选择正确的答案。你目前没有给回答你问题的人任何功劳。

标签: sql oracle select oracle11g


【解决方案1】:

您不需要所有这些子查询:

SELECT MAX(salary), MIN(salary)
FROM   employee

【讨论】:

  • 那么如果我想找到第二高和第二低的薪水,那么应该查询什么?
【解决方案2】:

SQL Fiddle

Oracle 11g R2 架构设置

CREATE TABLE employee ( EMP_ID,  F_NAME,  L_NAME,  SALARY,  JOINING_DATE, DEPARTMENT ) AS
          SELECT 101, 'John',      'Abraham', 100000, TIMESTAMP '2014-01-01 09:15:00', 'Banking'   FROM DUAL
UNION ALL SELECT 102, 'Michel',    'Clarke',  800000, NULL,                            'Insurance' FROM DUAL
UNION ALL SELECT 102, 'Roy',       'Thomas',   70000, TIMESTAMP '2013-02-01 12:30:00', 'Banking'   FROM DUAL
UNION ALL SELECT 103, 'Tom',       'Jose',    600000, TIMESTAMP '2014-02-03 01:30:00', 'Insurance' FROM DUAL
UNION ALL SELECT 105, 'Jerry',     'Pinto',   650000, TIMESTAMP '2013-02-01 12:00:00', 'Services'  FROM DUAL
UNION ALL SELECT 106, 'Philip',    'Mathew',  750000, TIMESTAMP '2013-01-01 02:00:00', 'Services'  FROM DUAL
UNION ALL SELECT 107, 'TestName1', '123',     650000, TIMESTAMP '2013-01-01 12:05:00', 'Services'  FROM DUAL
UNION ALL SELECT 108, 'TestName2', 'Lname%',  600000, TIMESTAMP '2013-01-01 12:00:00', 'Insurance' FROM DUAL;

查询 1 - 查找最高的 n 工资

SELECT *
FROM   (
  SELECT salary
  FROM   employee
  ORDER BY salary DESC
)
WHERE  rownum <= 3 -- replace with the number of salaries you want to retrieve.

Results

| SALARY |
|--------|
| 800000 |
| 750000 |
| 650000 |

查询 2 - 查找最低的 n 工资

SELECT *
FROM   (
  SELECT salary
  FROM   employee
  ORDER BY salary ASC
)
WHERE  rownum <= 3 -- replace with the number of salaries you want to retrieve.

Results

| SALARY |
|--------|
|  70000 |
| 100000 |
| 600000 |

【讨论】:

    【解决方案3】:

    对于查询返回的每一行,ROWNUM 伪列返回一个数字,指示 Oracle 从表或一组连接行中选择行的顺序。选择的第一行的 ROWNUM 为 1,第二行为 2,依此类推。

    所以在你的情况下:

    select max(salary) from (select * from (select salary from employee) where   rownum <2);
    

    这个查询将返回

    101    John     Abraham 100000  01-JAN-14 09.15.00.000000 AM    Banking
    

    仅此行作为输出...因此最大值仅为 100000。

    select max(salary) from (select * from (select salary from employee) where  rownum <3);
    

    此查询将从您的表中获取前 2 行,即,

    101    John     Abraham 100000  01-JAN-14 09.15.00.000000 AM    Banking
    102    Michel   Clarke  800000                                Insaurance
    

    因此最高工资将是 800000。

    同样,

    select min(salary)from (select * from(select salary from employee)where rownum<2);
    

    只会选择第一行

    select min(salary)from (select * from(select salary from employee)where rownum<2);
    

    所以最低工资将是 100000。

    附: :您可以像这样简单地编写查询:

    select max(salary) from  employee where rownum<[n];
    

    其中 n 将是您希望将查询返回的行数限制在其中的 ROWNUM

    【讨论】:

    • select max(salary) from employee where rownum 你完全错了。 ROWNUM 不会确保返回的行的顺序。它只是一个伪列,在返回行后分配。如果没有ORDER BY,则无法保证顺序并且随机返回行。见stackoverflow.com/a/30321788/3989608
    【解决方案4】:

    试试看:

    select *
    from (
      select T.*, rownum RRN
      from (
        select salary
        from employee
        order by salary desc) T)
    where RRN < 3
    

    【讨论】:

      【解决方案5】:

      所以你想要第二高和第二低的薪水?看看这个

      select max(salary), min(salary) from employee
      where salary < (select max(salary) from employee)
      and salary > (select min(salary) from employee)
      ;
      

      【讨论】:

        【解决方案6】:
        1) For lowest salary.
        select * from (
                       select empno,job,ename,sal 
                           from emp order by sal) 
                                  where rownum=1;
        
        2) For Highest salary.
        select * from (
                       select empno,job,ename,sal 
                           from emp order by sal desc)
                                  where rownum=1;
        

        【讨论】:

          【解决方案7】:

          我不知道你为什么要进行复杂的查询,你可以简单地写这个并得到相同的结果:

          select salary
          from employees
          where rownum <=3
          order by salary desc;
          

          【讨论】:

          • Rownumber 不能保证正确的结果,因为它很可能会在排序之前进行过滤。看起来目标是找到最高和最低的薪水,并且它是通过两个单独的查询来完成的。使用 SELECT TOP 1 查询将与 ORDER BY Salary DESC 和 ORDER BY Salary ASC 一起解决这个问题。希望对您有所帮助。
          【解决方案8】:

          您可以通过以下查询解决您的问题:

          最高薪水:

          Select * from Employee(Select salary from Employee ORDER BY salary DISC) where rownum=1;
          

          最低工资:

          Select * from Employee(Select salary from Employee ORDER BY salary) where rownum=1;
          

          第二高的薪水:

          Select MAX(Salary) from Employee 
          Where Salary < (Select MAX(Salary) from employee);
          

          第二低的薪水:

          Select MIN(Salary) from Employee 
          Where Salary > (Select MIN(Salary) from employee);
          

          【讨论】:

            猜你喜欢
            • 2021-08-26
            • 2016-05-01
            • 1970-01-01
            • 1970-01-01
            • 2018-06-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-01-16
            相关资源
            最近更新 更多