【问题标题】:Why this correlated subquery works differently in Oracle and SQL Server为什么此相关子查询在 Oracle 和 SQL Server 中的工作方式不同
【发布时间】:2023-03-10 15:39:02
【问题描述】:

我有表 EMPLOYEES,其中包含employee_id、department_id、salary 列(标准 HR 模式)。

为什么要查询:

SELECT 
    employee_id,
    department_id,
    salary,
    (
        select min(EMPLOYEES.salary) 
        from HR.EMPLOYEES E 
        where department_id = EMPLOYEES.department_id
    )
from HR.EMPLOYEES;

在 Oracle 中执行但在 SQL Server 中返回错误?

【问题讨论】:

  • 您能否通过“在 Oracle 中工作但在 SQL Server 中不工作”的意思给我们一个提示?
  • 我的错误:“在 Oracle 中执行,但在 SQL Server 中返回错误”更加精确。但我已经收到了答案。
  • 好的,一个更具描述性的帖子将有助于包含实际的错误消息。这很容易,但将来问题可能不会那么明显。欢迎来到 SO!

标签: sql sql-server oracle


【解决方案1】:

SQL Server 不允许在相关子查询的聚合中引用外部查询。这通常很好,因为这样的结构通常不是很有用。我很确定错误消息是这样说的。

我认为这是您真正想要的查询:

select e.employee_id, e.department_id, e.salary,
       (select min(e2.salary)
        from HR.EMPLOYEES E2
        where e2.department_id = e.department_id
       )
from HR.EMPLOYEES e;

建议您限定所有列引用,尤其是在相关子查询中。

您的版本将只返回外部查询中每个员工的薪水。您不需要相关的子查询来执行此操作。

【讨论】:

  • “SQL Server 不允许在相关子查询的聚合中引用外部查询。”你回答了我的问题。错误消息正是如此。当然,我不需要相关的子查询来做到这一点,我只是很惊讶为什么 Oracle 和 SQL Server 之间存在差异......
【解决方案2】:

您需要在子查询中限定department_id 列,否则它所引用的表是不明确的。某些 RDBMS 可能允许使用您的语法,但我不确定这是否会产生正确的结果。

为子查询返回的值提供别名也是一个好主意。

因此:

select
    employee_id,
    department_id,
    salary,
    (
        select min(e1.salary) 
        from hr.employees e1 
        where e1.department_id = e.department_id
    ) min_department_salary
from hr.employees e;

另外,请注意,您可以通过使用窗口函数(Oracle 和 SQLServer 已经支持很长时间)在不使用子查询的情况下获得相同的结果:

select
    employee_id,
    department_id,
    salary,
    min(salary) over(partition by department_id) min_department_salary
from hr.employees e;

【讨论】:

    猜你喜欢
    • 2020-08-02
    • 2022-01-23
    • 2019-06-25
    • 1970-01-01
    • 2020-11-27
    • 1970-01-01
    • 1970-01-01
    • 2018-09-09
    • 1970-01-01
    相关资源
    最近更新 更多