1
votes

Mettre à jour une valeur en fonction des critères de chaque identifiant unique

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   


1 commentaires

Votre requête ne met à jour rien.


3 Réponses :


1
votes

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)


0 commentaires

0
votes

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>


0 commentaires

0
votes

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.


1 commentaires

Je n'essaye pas de mettre à jour la table elle-même. Merci pour l'aide en tout cas