Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Oracle SQL - Help using Case in a Select Statement

CREATE TABLE student_totalexp2 nologging compress AS
SELECT /*+parallel(a,4)*/ DISTINCT a.member_sk, 
       CASE 
         WHEN b.end_date IS NULL THEN 
           SYSDATE - MIN(TO_DATE(b.start_date,'yyyymm'))
         ELSE 
           (MAX(TO_DATE(b.end_date,'yyyymm')) - MIN(TO_DATE(b.start_date,'yyyymm')))  
       END as days_experience
  FROM student_schools a 
  JOIN rdorwart.position_rd b ON a.member_sk = b.member_sk 
 WHERE days_experience < 730 
 GROUP BY a.member_sk;

SELECT COUNT(*) 
  FROM student_experience; 

Any idea why I keep getting this error: Error report:

SQL Error: ORA-00904: "DAYS_EXPERIENCE": invalid identifier 00904. 00000 - "%s: invalid identifier" *Cause:
*Action:

like image 562
AME Avatar asked Dec 21 '22 17:12

AME


2 Answers

You cannot reference a alias in the WHERE clause. Either use a subquery, or better just the entire CASE...END into your where clause.

Updated query per OP's comments:

create table student_totalexp2 nologging compress as 
SELECT a.member_sk, 
 SUM(CASE WHEN b.end_date IS NULL
    THEN sysdate 
    ELSE to_date(b.end_date,'yyyymm') 
  END - to_date(b.start_date,'yyyymm')) as days_experience
FROM student_schools a INNER JOIN rdorwart.position_rd b 
  ON a.member_sk = b.member_sk 
GROUP BY a.member_sk
HAVING SUM(
  CASE WHEN b.end_date IS NULL
    THEN sysdate 
    ELSE to_date(b.end_date,'yyyymm') 
  END - to_date(b.start_date,'yyyymm')
  ) < 730;
SELECT COUNT(*) FROM student_experience; 
like image 77
The Scrum Meister Avatar answered Jan 03 '23 08:01

The Scrum Meister


The below is a direct simplification of the query in the question, taking MAX (any row) against MIN (any row). The Scrum Meister's answer fixes the OP's logic as well, to correctly cater for gaps between jobs.


This should be all you need. Having the student_schools table JOINed seems to add no value, unless there are cases where position_rd records exist without a student_schools record.
CREATE TABLE student_totalexp2 nologging compress AS
SELECT b.member_sk, 
    NVL(MAX(TO_DATE(b.end_date,'yyyymm')), SYSDATE)
      - MIN(TO_DATE(b.start_date,'yyyymm')) as days_experience
FROM rdorwart.position_rd b
GROUP BY b.member_sk
HAVING NVL(MAX(TO_DATE(b.end_date,'yyyymm')), SYSDATE)
         - MIN(TO_DATE(b.start_date,'yyyymm')) < 730 
  • The NVL takes care of replacing a non-existent end_date with SYSDATE

If you do need to validate student_schools - just add an INNER JOIN to it. Nowhere else is it needed.

like image 44
RichardTheKiwi Avatar answered Jan 03 '23 06:01

RichardTheKiwi