【问题标题】:Single-row subquery returns more than one row单行子查询返回多于一行
【发布时间】:2011-09-11 22:31:17
【问题描述】:

我需要一些有关 oracle sql 的帮助。问题:我有 2 张表员工和部门。我从一个查询中得到了部门的平均工资,我想用它来看看有多少员工比他们部门的平均工资多。到目前为止我有这个。

此查询返回部门的平均值:

select ROUND(AVG(Salary), 2) Dept_avg_sal
 from employee, department
 where department.department_id = employee.department_id
 group by department_name

我想做的是:

select employee_name,
       salary,
       d.department_name
from   employee e,
       department d
where  salary > (select ROUND(AVG(Salary), 2) Dept_avg_sal
                 from   employee,
                        department
                 where  department.department_id = employee.department_id
                 group  by department_name)  

我得到的错误是:01427。 00000 - “单行子查询返回多于一行”

我知道同一部门的 2 名员工的收入高于平均水平,我认为这就是造成问题的原因。

EMPLOYEE_NAME       - SALARY -                -DEPARTMENT_NAME-      DEPT_AVG_SAL           
-------------------- ---------------------- -------------------- ------------ 
FISHER              - 3000.00  -              SALES      -          2500.00                   
JONES          -      3000.00               - ACCOUNTING         -  2750.00                   
KING             -    5000.00           -     EXECUTIVE     -       4500.00                   
**SCOTT           -     2500.00           -     IT             -      2100.00                   
SMITH           -     2900.00          -      IT     -              2100.00**                   
WILSON           -    3000.00          -      RESEARCH      -       2633.33 

任何帮助将不胜感激。

【问题讨论】:

  • 你为什么要标记这个 MySQL 你需要一个适用于 Oracle 和 MySQL 的答案吗?

标签: sql oracle


【解决方案1】:

您的初始查询缺少外部查询中的任何连接条件以及内部查询中的任何相关条件,这会将其限制为感兴趣部门的行。通常你也不想group by name 因为大概id 是主键。

解决这些问题以修复您的相关子查询给出了

SELECT e.employee_name,
       e.salary,
       d.department_name
FROM   employee e
       JOIN department d
         ON d.department_id = e.department_id
WHERE  e.salary > (SELECT ROUND(AVG(Salary), 2) Dept_avg_sal
                   FROM   employee e2
                   WHERE  e2.department_id = e.department_id)  

但您可能会发现放弃标量相关子查询并用派生表替换效果更好。

SELECT e.employee_name,
       e.salary,
       d.department_name
FROM   employee e
       JOIN department d
         ON d.department_id = e.department_id
       JOIN (SELECT ROUND(AVG(Salary), 2) Dept_avg_sal,
                    department_id
             FROM   employee
             GROUP  BY department_id) e2
         ON e2.department_id = e.department_id
            AND e.salary > e2.Dept_avg_sal  

我相信以下对于 Oracle 也应该有效

SELECT employee_name,
       salary,
       d.department_name
FROM   (SELECT employee_name,
               salary,
               d.department_name,
               AVG(Salary) OVER (PARTITION BY e.department_id) AS AvgSalary
        FROM   employee e
               JOIN department d
                 ON d.department_id = e.department_id)
WHERE  salary > AvgSalary  

【讨论】:

    【解决方案2】:

    > 运算符只接受一个值,因此您的内部 SELECT 必须准确返回 1 行。我的猜测是你得到多行。查看您的内部 SELECT 返回的内容并尝试 LIMIT 1。

    【讨论】:

      【解决方案3】:

      我认为您应该在子查询中添加一个额外的d.department_id = department.department_id 条件(未测试):

      select employee_name,
             salary,
             d.department_name
      from   employee e,
             department d
      where  salary > (select ROUND(AVG(Salary), 2) Dept_avg_sal
                       from   employee,
                              department
                       where  department.department_id = employee.department_id 
                       AND d.department_id = department.department_id
                       group  by department_name)  
      

      或者直接写:

      select e.employee_name,
             e.salary,
             d.department_name
      from   employee e,
             department d
      where  e.department_id = d.department_id
             AND salary > (select ROUND(AVG(Salary), 2) Dept_avg_sal
                       from employee
                       where e.department_id = employee.department_id)  
      

      【讨论】:

        猜你喜欢
        • 2017-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多