Oracle SQL - Справка по использованию регистра в операторе выбора - PullRequest
4 голосов
/ 17 февраля 2011
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; 

Любая идея, почему я продолжаю получать эту ошибку: Отчет об ошибке:

Ошибка SQL: ORA-00904: «DAYS_EXPERIENCE»: неверный идентификатор 00904. 00000 - «% s: неверный идентификатор"* Причина:
* Действие:

Ответы [ 4 ]

9 голосов
/ 17 февраля 2011

Нельзя ссылаться на псевдоним в предложении WHERE. Или используйте подзапрос, или лучше всего весь CASE...END в вашем предложении where.

Обновлен запрос для комментариев ОП:

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; 
2 голосов
/ 17 февраля 2011

Ниже приведено прямое упрощение запроса в вопросе, взяв MAX (любая строка) против MIN (любая строка). Ответ Скрама Мейстера также исправляет логику ОП, чтобы правильно обрабатывать промежутки между заданиями.


Это должно быть все, что вам нужно. Наличие таблицы student_schools JOINed, по-видимому, не добавляет значения, если только не существует случаев, когда существуют записи position_rd без записи student_schools.
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 
  • NVL заботится о замене несуществующей конечной даты на SYSDATE

Если вам нужно проверить student_schools - просто добавьте ВНУТРЕННЕЕ СОЕДИНЕНИЕ. Больше нигде это не нужно.

0 голосов
/ 06 июня 2014

Для краткого и более читабельного кода используйте внешний SELECT:

CREATE TABLE student_totalexp2 nologging compress AS
SELECT member_sk, days_experience FROM (
    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)
WHERE days_experience < 730;


SELECT COUNT(*)
FROM student_experience;
0 голосов
/ 17 февраля 2011

вы не можете использовать название поля, введенное в поле, непосредственно в предложении where. Вам нужно повторить логику, в которой пункт

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 INNER JOIN rdorwart.position_rd b        
ON a.member_sk = b.member_sk          
where (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) < 730          
group by a.member_sk;     
select count(*) from student_experience;
...