2010-03-19 6 views
1

Dans Oracle 10g, je dois mettre à jour le tableau A avec les données du tableau B.Mise à jour d'une table avec la date maximum d'une autre table

Tableau A LIEU a, trandate et STATUS.

Tableau B a LIEU, STATUSDATE et STATUT

Je dois mettre à jour la colonne d'état dans le tableau A avec la colonne d'état du tableau B où le STATUSDATE est la date max jusqu'à et y compris la trandate pour cet emplacement (Fondamentalement, je reçois le statut de l'emplacement au moment d'une transaction particulière).

J'ai une procédure PL/SQL qui va le faire mais JE SAIS qu'il doit y avoir un moyen de le faire fonctionner en utilisant un analytique, et je me suis cogné la tête trop longtemps.

Merci!

Répondre

2

cela devrait vous commencer (ici la fonction MAX est la fonction globale et non la fonction analytique):

UPDATE table_a 
    SET status = (SELECT MAX(table_b.status) 
         KEEP (DENSE_RANK FIRST ORDER BY table_b.statusdate DESC) 
        FROM table_b 
        WHERE table_a.location = table_b.location 
        AND table_b.statusdate <= table_a.trandate); 

Cela mettra à jour toutes les lignes table_a, même s'il n'y a pas de ligne préalable table_b , mettant à jour le statut à NULL dans ce cas. Si vous ne souhaitez que mettre à jour les lignes table_a qui ont un match correspondant à table_b vous pouvez ajouter un filtre:

UPDATE table_a 
    SET status = (SELECT MAX(table_b.status) 
         KEEP (DENSE_RANK FIRST ORDER BY table_b.statusdate DESC) 
        FROM table_b 
        WHERE table_a.location = table_b.location 
        AND table_b.statusdate <= table_a.trandate) 
WHERE EXISTS (SELECT NULL 
       FROM table_b 
       WHERE table_a.location = table_b.location 
        AND table_b.statusdate <= table_a.trandate); 
0

Ceci est une version avec la fonction analytique. Il met à jour toutes les lignes dans table_a comme indiqué. Pour mettre à jour une ligne spécifique, ajoutez un filtre.

update table_a t1 set status = (
     select distinct 
       first_value(t2.status) over (partition by t1.location, t1.trandate order by t2.statusdate desc) 
     from temp_b t2 
     where t1.location = t2.location 
     and t2.statusdate <= t1.trandate); 
Questions connexes