带有 CASE 和 JOIN SUBQUERY 的 Oracle SQL 查询

Posted

技术标签:

【中文标题】带有 CASE 和 JOIN SUBQUERY 的 Oracle SQL 查询【英文标题】:Oracle SQL query with CASE and JOIN SUBQUERY 【发布时间】:2020-11-06 16:11:30 【问题描述】:

我正在尝试在 Oracle 中编写一个 SQL 查询来按等级返回员工工资。我正在使用子查询来确定每个年级的工资范围。 下面的查询不起作用,它系统返回“ORA-00936: missing expression”错误。

我做错了什么?

SELECT a.last_name, a.salary, b.grade_level, b.lowest_sal, b.highest_sal 
FROM employees a 
JOIN (
    SELECT 
       CASE salary 
        WHEN BETWEEN 1000 AND 2999 THAN 'A' 
       WHEN BETWEEN 3000 AND 5999 THAN 'B' 
        ELSE 'C' 
        END AS grade_level,
       MIN(salary) AS lowest_sal, MAX(salary) AS highest_sal
   FROM employees 
   GROUP BY grade_level)  b 
ON(a.salary BETWEEN b.lowest_sal AND b.highest_sal) 
ORDER BY last_name; 

【问题讨论】:

编辑您的问题并提供示例数据和预期结果。我会注意到,Oracle 不允许在GROUP BY 子句中使用表别名。 Case...when...then (not than) 感谢您的 cmets 【参考方案1】:

我认为窗口函数是更好的方法:

SELECT e.*,
       MIN(salary) OVER (PARTITION BY grade_level) as lowest_sal,
       MAX(salary) OVER (PARTITION BY grade_level) as highest_sal
FROM (SELECT (CASE WHEN salary BETWEEN 1000 AND 2999 THAN 'A'
                   WHEN salary BETWEEN 3000 AND 5999 THAN 'B'
                   ELSE 'C'
              END) AS grade_level,
             e.*
      FROM employees e
     ) e
ORDER BY last_name ;

请注意,这还修复了 CASE 表达式,该表达式在您的查询中也存在语法错误。

【讨论】:

谢谢你,Gordon 和 HelenA 。从员工中选择 a.last_name、a.salary、b.grade_level、b.lowest_sal、b.highest_sal 加入(当工资在 1000 和 2999 之间时选择案例,然后在工资在 3000 和 5999 之间时选择“A”,然后选择“B”否则“C” ' END ASgrade_level, MIN(salary) AS minimum_sal, MAX(salary) AS highest_sal FROM employees GROUP BY Salary) b ON(a.salary BETWEEN b.lowest_sal AND b.highest_sal) ORDER BY last_name ;【参考方案2】:

谢谢你,Gordon 和 HelenA 。您的 cmets 帮助我找到了代码中的错误。

    我的 CASE 表达式中有错误的语法 GROUP BY 中的表别名。
SELECT a.last_name, a.salary, b.grade_level, b.lowest_sal, b.highest_sal
FROM employees a
JOIN (
  SELECT CASE
     WHEN salary BETWEEN 1000 AND 2999 THEN 'A'
       WHEN  salary BETWEEN 3000 AND 5999 THEN 'B'
       ELSE 'C'
       END AS grade_level,
   MIN(salary) AS lowest_sal, MAX(salary) AS highest_sal
  FROM employees
  GROUP BY salary) b
ON(a.salary BETWEEN b.lowest_sal AND b.highest_sal)
ORDER BY last_name ;

输出:

LAST_NAME   SALARY  GRADE_LEVEL LOWEST_SAL  HIGHEST_SAL
Abel        11000   C           11000       11000
Davies       3100   B           3100        3100
De Haan     17000   C           17000       17000
Ernst        6000   C           6000        6000
Fay          6000   C           6000        6000
Gietz        8300   C           8300        8300
Grant        7000   C           7000        7000
Hartstein   13000   C           13000       13000

【讨论】:

以上是关于带有 CASE 和 JOIN SUBQUERY 的 Oracle SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

带有条件 CASE 语句的 SQL LEFT JOIN

Mysql join with subquery join 使用相关名称

Hibernate Criteria:在 Subquery/DetachedCriteria 中执行 JOIN

将这些 DB2 SUBQUERY 重写为 Join

MySQL Left Join Subquery with *

MySQL LEFT JOIN 或 WHERE IN SUBQUERY