Oracle SQL - Aide à utiliser le cas dans une instruction SELECT
Question
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;
Toute idée de la raison pour laquelle je continue d'obtenir cette erreur: Rapport d'erreur:
Erreur SQL: ORA-00904: "Days_Experience": Identificateur non valide 00904. 00000 - "% S: Identificateur non valide" * Cause:
*Action:
La solution
Vous ne pouvez pas référencer un alias dans le WHERE
clause. Soit utiliser une sous-requête, soit mieux tout CASE...END
dans votre clause où.
Query mis à jour conformément aux commentaires de l'OP:
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;
Autres conseils
Ci-dessous est une simplification directe de la requête dans la question, en prenant max (n'importe quelle ligne) contre MIN (n'importe quelle ligne). La réponse du Scrum Meister Corrige également la logique de l'OP, pour répondre correctement aux lacunes entre les travaux.
Cela devrait être tout ce dont vous avez besoin. Avoir le tableau Student_Schools joint ne semble ajouter aucune valeur, sauf s'il y a des cas où des enregistrements de position_rd existent sans un
student_schools
enregistrement.
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
- Le NVL s'occupe de remplacer une end_date inexistante par Sysdate
Si vous avez besoin de valider student_schools
- Il suffit d'ajouter une jointure intérieure. Nulle part ailleurs n'est nécessaire.
Vous ne pouvez pas utiliser le nom de giveau du champ directement dans la clause où. Vous devez répéter la logique dans la clause
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;
Pour un code court et plus lisible, utilisez une sélection extérieure:
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;