IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Oracle Discussion :

Transformer and exists en MERGE INTO


Sujet :

SQL Oracle

  1. #1
    Membre averti
    Inscrit en
    Mai 2011
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Mai 2011
    Messages : 29
    Par défaut Transformer and exists en MERGE INTO
    Bonjour,

    je veux transformer cette requette trop lente en Merge into mais j'ai deux conditions and exists comment je peut transformer la requette correctement

    requette initiale

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    UPDATE DR_POS pos
      set MtIntInterPer = (select max(MtFlx) from DR_ECH_OPE ech
                           where ech.DateCurrent = '03/01/2019' AND ech.IdOpe = pos.IdOpe AND ech.IdJmb = pos.IdJmb AND ech.CdTypOpe = pos.CdTypOpe AND ech.CdTypFlx in ('INT', 'IPR') 
                           and ech.DtVal=pos.DtProPaiInt)
      where datecurrent = '03/01/2019'  AND CdEtab = 'BPCE'
      AND exists (select 1 from DR_ECH_OPE ech
                  where ech.DateCurrent = '03/01/2019' AND ech.IdOpe = pos.IdOpe AND ech.IdJmb = pos.IdJmb AND ech.CdTypOpe = pos.CdTypOpe AND ech.CdTypFlx in ('INT', 'IPR') 
                  and ech.DtVal=pos.DtProPaiInt )
      AND exists (select 1 from DR_ECH_OPE ech
                  where ech.DateCurrent = '03/01/2019' AND ech.IdOpe = pos.IdOpe AND ech.IdJmb = pos.IdJmb AND ech.CdTypOpe = pos.CdTypOpe AND ech.CdTypFlx in ('INT', 'IPR')   
                  and DtFinPer=pos.DTARRETE);
    ma requette que j'ai essayé de tester mais elle me renvoie pas le même nombre de ligne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Merge into  DR_POS pos
    using (select max(ech.MtFlx) max_mtflx ,ech.DateCurrent,ech.IdOpe,ech.IdJmb ,ech.CdTypOpe,ech.CdTypFlx,ech.DtVal, ech.DtFinPer from DR_ECH_OPE ech
           where ech.DateCurrent = '03/01/2019' AND ech.CdTypFlx in ('INT', 'IPR') group by ech.DateCurrent, ech.IdOpe, ech.IdJmb, ech.CdTypOpe, ech.CdTypFlx, 
                 ech.DtVal, ech.DtFinPer  ) ech
    on((pos.datecurrent = '03/01/2019'  AND pos.CdEtab = 'BPCE' and ech.IdOpe = pos.IdOpe AND ech.IdJmb = pos.IdJmb AND ech.CdTypOpe = pos.CdTypOpe  
        and ech.DtVal=pos.DtProPaiInt ) and (ech.DateCurrent = '03/01/2019' AND ech.IdOpe = pos.IdOpe AND ech.IdJmb = pos.IdJmb AND ech.CdTypOpe = pos.CdTypOpe AND ech.CdTypFlx in ('INT', 'IPR')   
                  and ech.DtFinPer=pos.DTARRETE))
     
    when matched then 
    update set MtIntInterPer=max_mtflx ;
    Merci

  2. #2
    Expert confirmé
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 427
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 427
    Par défaut
    Bonjour,
    Le problème est que le "critère" n'est pas le même dans les deux requêtes.
    Je vais simplifier la deuxième requête:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ...
    (pos.datecurrent = '03/01/2019' AND ech.IdOpe = pos.IdOpe AND ech.IdJmb = pos.IdJmb AND ech.CdTypOpe = pos.CdTypOpe AND pos.CdEtab = 'BPCE' and ech.DtVal=pos.DtProPaiInt )
    and
    (ech.DateCurrent = '03/01/2019' AND ech.IdOpe = pos.IdOpe AND ech.IdJmb = pos.IdJmb AND ech.CdTypOpe = pos.CdTypOpe AND ech.CdTypFlx in ('INT', 'IPR') and ech.DtFinPer=pos.DTARRETE)
    ...
    Comme il n'y a que des AND, on peut supprimer les parenthèses et les critères en double:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ...
    pos.datecurrent = '03/01/2019' AND ech.IdOpe = pos.IdOpe  AND ech.IdJmb = pos.IdJmb AND ech.CdTypOpe = pos.CdTypOpe AND pos.CdEtab = 'BPCE' and ech.DtVal=pos.DtProPaiInt
    and ech.DateCurrent = '03/01/2019' and ech.DtVal=pos.DtProPaiInt AND ech.CdTypFlx in ('INT', 'IPR') and ech.DtFinPer=pos.DTARRETE
    ...

    Maintenant que c'est fait, que font les deux requêtes ? La première fait la mise à jour des lignes de DR_POS pour les quelles il existe 2 lignes dans DR_ECH_OPE:
    • La première, avec ces critères :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      ech.DateCurrent = '03/01/2019' AND ech.IdOpe = pos.IdOpe AND ech.IdJmb = pos.IdJmb AND ech.CdTypOpe = pos.CdTypOpe AND ech.CdTypFlx in ('INT', 'IPR') 
      and ech.DtVal=pos.DtProPaiInt
    • La deuxième avec ces critères :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      ech.DateCurrent = '03/01/2019' AND ech.IdOpe = pos.IdOpe AND ech.IdJmb = pos.IdJmb AND ech.CdTypOpe = pos.CdTypOpe AND ech.CdTypFlx in ('INT', 'IPR') 
      and DtFinPer=pos.DTARRETE


    Et la deuxième ne cherche qu'une seule ligne dans DR_ECH_POS, avec des critères différents (surtout ech.DtVal=pos.DtProPaiInt and DtFinPer=pos.DTARRETE). Ça revient à faire la première requête, mais avec un seul EXISTS qui regroupe les deux.

    Tatayo.

  3. #3
    Membre averti
    Inscrit en
    Mai 2011
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Mai 2011
    Messages : 29
    Par défaut
    Merci pour Votre Réponse,
    vous voulez dire que je dois mettre les deux condition and ech.DtVal=pos.DtProPaiIn and DtFinPer=pos.DTARRETE dans le premier EXISTS si le cas j'ai bien testé mais la requette ne renvoie pas le même nombre de lignes avec la requette original c'est pour cette raison j'ai pensé a transformer en MERGE INTO mais sans succés

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    UPDATE DR_POS pos
      set MtIntInterPer = (select max(MtFlx) from DR_ECH_OPE ech
                           where ech.DateCurrent = '03/01/2019' AND ech.IdOpe = pos.IdOpe AND ech.IdJmb = pos.IdJmb AND ech.CdTypOpe = pos.CdTypOpe AND ech.CdTypFlx in ('INT', 'IPR') 
                           and ech.DtVal=pos.DtProPaiInt)
      where datecurrent = '03/01/2019'  AND CdEtab = 'BPCE'
      AND exists (select 1 from DR_ECH_OPE ech
                  where ech.DateCurrent = '03/01/2019' AND ech.IdOpe = pos.IdOpe AND ech.IdJmb = pos.IdJmb AND ech.CdTypOpe = pos.CdTypOpe AND ech.CdTypFlx in ('INT', 'IPR') 
                  and ech.DtVal=pos.DtProPaiIn   and DtFinPer=pos.DTARRETE )

  4. #4
    Expert confirmé
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 427
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 427
    Par défaut
    Citation Envoyé par jerbien13 Voir le message
    Merci pour Votre Réponse,
    vous voulez dire que je dois mettre les deux condition and ech.DtVal=pos.DtProPaiIn and DtFinPer=pos.DTARRETE dans le premier EXISTS si le cas j'ai bien testé mais la requette ne renvoie pas le même nombre de lignes avec la requette original c'est pour cette raison j'ai pensé a transformer en MERGE INTO mais sans succés
    Non, je pointais le fait que les critères ne sont pas les mêmes entre les deux requêtes, d'où la différence de résultat.
    Le problème ici est que chaque sous-requête dans les clause EXISTS peuvent "trouver" une ligne différente de la table DR_ECH_OPE.
    Peut-être que ceci peut fonctionner pour fusionner les deux sous-requêtes et ainsi n'avoir qu'un seul EXISTS(mais j'ai un petit doute):

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select count(*) from DR_ECH_OPE ech
    where ech.DateCurrent = '03/01/2019' AND ech.IdOpe = pos.IdOpe AND ech.IdJmb = pos.IdJmb AND ech.CdTypOpe = pos.CdTypOpe AND ech.CdTypFlx in ('INT', 'IPR') 
    and (ech.DtVal=pos.DtProPaiInt or DtFinPer=pos.DTARRETE) having count(*) = 2

    Par contre je ne vois pas trop comment faire un MERGE avec tout ça.

    Tatayo.

  5. #5
    Membre averti
    Inscrit en
    Mai 2011
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Mai 2011
    Messages : 29
    Par défaut
    j'ai trouvé la solution j'ai gagné beaucoup de temps en terme de performance
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Merge into  DR_POS pos
    using (select max(ech.MtFlx) max_mtflx ,ech.IdOpe,ech.IdJmb ,ech.CdTypOpe,ech.DtVal 
                           from DR_ECH_OPE ech 
                           where ech.DateCurrent = '03/01/2019'   AND ech.CdTypFlx in ('INT', 'IPR')  
                           group by  ech.IdOpe, ech.IdJmb, ech.CdTypOpe,ech.DtVal 
                           ) ech
    on( pos.datecurrent = '03/01/2019'  AND pos.CdEtab = 'BPCE' and ech.IdOpe = pos.IdOpe AND ech.IdJmb = pos.IdJmb AND ech.CdTypOpe = pos.CdTypOpe and ech.DtVal=pos.DtProPaiInt 
                  AND exists (select 1 from DR_ECH_OPE ech2
                  where ech2.DateCurrent = '03/01/2019' AND ech2.IdOpe = pos.IdOpe AND ech2.IdJmb = pos.IdJmb AND ech2.CdTypOpe = pos.CdTypOpe   AND ech2.CdTypFlx in ('INT', 'IPR') 
                  and ech2.DtFinPer=pos.DTARRETE))
    when matched then 
    update set pos.MtIntInterPer= ech.max_mtflx  ;

Discussions similaires

  1. Transcrire "Merge into"
    Par Ndrmar dans le forum SQL
    Réponses: 6
    Dernier message: 11/09/2008, 12h24
  2. SQL Merge into - delete ne marche pas
    Par Javotte dans le forum Langage SQL
    Réponses: 1
    Dernier message: 30/06/2008, 09h29
  3. Réponses: 4
    Dernier message: 11/10/2007, 08h51
  4. 9i : problème avec MERGE INTO
    Par Vld44 dans le forum SQL
    Réponses: 1
    Dernier message: 16/08/2007, 11h27
  5. Multiplier les And dans Sql Insert Into
    Par samlepiratepaddy dans le forum Requêtes et SQL.
    Réponses: 17
    Dernier message: 23/09/2005, 21h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo