J'ai une requête dans laquelle je voudrais mettre à jour une valeur basée sur une certaine condition pour chaque clé primaire. Par exemple, partout où TYPE est "AMIANTE" et TYPE "CONTIN" n'est pas présent pour ce projet spécifique, j'aimerais changer le "AMIANTE" en "CONTIN".
J'ai atteint cet objectif avec la requête ci-dessous, mais cela met à jour l'ensemble des valeurs ASBESTOS des populations sur CONTIN, même si CONTIN est déjà présent, ce qui entraîne essentiellement des valeurs en double. Ne devrait l'ajouter que si CONTIN n'est pas déjà présent. Peut-être qu'une fonction Windows fonctionnera pour qu'elle examine chaque projet individuel, mais j'obtiens une erreur de syntaxe. Merci pour votre aide!
SELECT PROJECT, CASE WHEN TYPE = 'ASBESTOS' AND TYPE NOT IN 'CONTIN' THEN 'CONTIN' ELSE TYPE END AS TYPE, SUM(OBLIGATION) AS OBS FROM OBS_MASTER WHERE PROJECT = '074190' GROUP BY PROJECT, TYPE; Original: PROJECT TYPE OBS 074190 ASBESTOS 26326.99 074190 CM 0 Current Result: PROJECT TYPE OBS 074190 CM 0 074190 CONTIN 26326.99
3 Réponses :
Si je comprends bien, vous pouvez utiliser les fonctions de fenêtre pour compter le nombre de "CONTIN" pour chaque projet, puis utiliser ces informations pour la clé d'agrégation:
SELECT PROJECT, (CASE WHEN NUM_CONTIN = 0 AND TYPE = 'ASBESTOS' THEN 'CONTIN' ELSE TYPE END) as TYPE SUM(OBLIGATION) AS OBS FROM (SELECT om.*, SUM(CASE WHEN TYPE = 'CONTIN' THEN 1 ELSE 0 END) OVER (PARTITION BY PROJECT) as NUM_CONTIN FROM OBS_MASTER om ) om WHERE PROJECT = '074190' GROUP BY PROJECT, (CASE WHEN NUM_CONTIN = 0 AND TYPE = 'ASBESTOS' THEN 'CONTIN' ELSE TYPE END)
Voici une autre option:
SQL> with 2 obs_master (project, type, obligation) as 3 -- sample data 4 (select 1, 'ASBESTOS', 2500 from dual union all 5 select 1, 'CONTIN' , 1500 from dual union all 6 select 1, 'CM' , 500 from dual union all 7 -- 8 select 2, 'ASBESTOS', 1000 from dual union all 9 select 2, 'CM' , 1000 from dual 10 ), 11 temp as 12 -- check whether project has CONTIN type 13 (select project, min(type) cb_contin 14 from obs_master 15 group by project, type 16 having type = 'CONTIN' 17 ) 18 select a.project, 19 -- if type = ASBESTOS and that project doesn't contain CONTIN, 20 -- replace ASBESTOS with CONTIN 21 case when a.type = 'ASBESTOS' and 22 b.cb_contin <> 'CONTIN' 23 then 'CONTIN' 24 else a.type 25 end type, 26 sum(a.obligation) obs 27 from obs_master a left join temp b on a.project = b.project 28 group by a.project, 29 case when a.type = 'ASBESTOS' and 30 b.cb_contin <> 'CONTIN' 31 then 'CONTIN' 32 else a.type 33 end 34 order by a.project; PROJECT TYPE OBS ---------- -------- ---------- 1 ASBESTOS 2500 1 CM 500 1 CONTIN 1500 2 ASBESTOS 1000 2 CM 1000 SQL>
Si votre objectif est simplement de mettre à jour les valeurs de type, alors quelque chose comme l'instruction ci-dessous pourrait fonctionner:
UPDATE OBS_MASTER SET TYPE='CONTIN' WHERE TYPE='ASBESTOS' and PROJECT not in (select distinct PROJECT from OBS_MASTER where TYPE='CONTIN')
J'espère que cela vous aidera.
Je n'essaye pas de mettre à jour la table elle-même. Merci pour l'aide en tout cas
Votre requête ne met à jour rien.