SQL / PLSQL Oracle查询:WHERE语句中的CASE

时间:2018-05-18 14:42:47

标签: sql oracle plsql

我正在尝试查询oracle数据库,但无法让脚本正常工作。该脚本用于搜索两个日期之间start_date的员工。遗憾的是,并非所有员工在数据库中都有start_date,但所有员工都有create_date。我想做的是:

IF START_DATE IS NULL:
    (E.START_DATE >= TO_DATE('10/29/2014', 'MM/DD/YYYY') AND E.START_DATE <= TO_DATE('10/29/2016', 'MM/DD/YYYY')
ELSE: 
    (E.CREATE_DATE >= TO_DATE('10/29/2014', 'MM/DD/YYYY') AND E.CREATE_DATE <= TO_DATE('10/29/2016', 'MM/DD/YYYY')

这是我到目前为止所做的:

SELECT OC.DESCRIPTION "Description",
sum(S.AMOUNT) "SUM",
COUNT (DISTINCT(E.EMPLOYEE_NUM)) "Employee Nums"
FROM EMPLOYEES E
JOIN EMPLOYEE_SPENDING S ON S.EMPLOYEE_ID = E.EMPLOYEE_ID
WHERE E.EMPLOYEE_CATEGORY IN ('ACTIVE', 'INACTIVE')
AND ((E.START_DATE >= TO_DATE('10/29/2014', 'MM/DD/YYYY') AND E.START_DATE <= TO_DATE('10/29/2016', 'MM/DD/YYYY'))
OR (E.CREATE_DATE >= TO_DATE('10/29/2014', 'MM/DD/YYYY') AND E.CREATE_DATE <= TO_DATE('10/29/2016', 'MM/DD/YYYY')))
GROUP BY E.EMPLOYEE_CATEGORY;

我的案例陈述看起来像这样:

SELECT OC.DESCRIPTION "Description",
sum(S.AMOUNT) "SUM",
COUNT (DISTINCT(E.EMPLOYEE_NUM)) "Employee Nums"
FROM EMPLOYEES E
JOIN EMPLOYEE_SPENDING S ON S.EMPLOYEE_ID = E.EMPLOYEE_ID
WHERE E.EMPLOYEE_CATEGORY IN ('ACTIVE', 'INACTIVE')
AND (CASE WHEN E.START_DATE IS NULL THEN (E.START_DATE >= TO_DATE('10/29/2014', 'MM/DD/YYYY') AND E.START_DATE <= TO_DATE('10/29/2016', 'MM/DD/YYYY'))
ELSE (E.CREATE_DATE >= TO_DATE('10/29/2014', 'MM/DD/YYYY') AND E.CREATE_DATE <= TO_DATE('10/29/2016', 'MM/DD/YYYY'))
END
GROUP BY E.EMPLOYEE_CATEGORY;

我对Oracle或PLSQL并不是很熟悉,所以您可以提供的任何帮助都会非常感激!

提前致谢!

2 个答案:

答案 0 :(得分:2)

我相信你有倒退的逻辑。这更有意义:

IF START_DATE IS NOT NULL:
    (E.START_DATE >= TO_DATE('10/29/2014', 'MM/DD/YYYY') AND E.START_DATE <= TO_DATE('10/29/2016', 'MM/DD/YYYY')
ELSE: 
    (E.CREATE_DATE >= TO_DATE('10/29/2014', 'MM/DD/YYYY') AND E.CREATE_DATE <= TO_DATE('10/29/2016', 'MM/DD/YYYY')

然后,您可以将其表达为:

where (e.start_date >= date '2014-10-29' and e.start_date <= date '2016-10-29') or
      (e.start_date is null and e.create_date >= date '2014-10-29' and e.start_date <= date '2016-10-29')

请注意,我已经简化了&#34;日期常数&#34;使用date关键字后跟ISO标准日期。

这可以进一步简化为:

where coalesce(e.start_date, e.create_date) >= date '2014-10-29' and
      coalesce(e.start_date, e.create_date) <= date '2016-10-29'

通常,您希望避免case子句中的where,因为基本的布尔表达式通常很容易编写和理解。使用case的时间是您明确要对条件进行排序的时间,特别是当一个条件可能是一个昂贵的函数调用时。

答案 1 :(得分:0)

像这样使用nvl:

SELECT OC.DESCRIPTION "Description",
sum(S.AMOUNT) "SUM",
COUNT (DISTINCT(E.EMPLOYEE_NUM)) "Employee Nums"
FROM EMPLOYEES E
JOIN EMPLOYEE_SPENDING S ON S.EMPLOYEE_ID = E.EMPLOYEE_ID
WHERE E.EMPLOYEE_CATEGORY IN ('ACTIVE', 'INACTIVE')
AND ((nvl(E.START_DATE, e.create_date) >= TO_DATE('10/29/2014', 'MM/DD/YYYY') AND (nvl(E.START_DATE, e.create_date) <= TO_DATE('10/29/2016', 'MM/DD/YYYY'))
GROUP BY E.EMPLOYEE_CATEGORY;