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

Oracle Discussion :

Requete un peu complexe avec la fonction IN


Sujet :

Oracle

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    15
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 15
    Points : 17
    Points
    17
    Par défaut [Résolu]Requete un peu complexe avec la fonction IN
    Bonjour,

    Je travaille actuellement sur le développement d'une base décisionelle pour mon job et j'aurais besoin de faire une requete avec un "IN" sur deux champs de base de données

    j'ai essayé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from table1 where (champ1, champ2 IN (select champ1, champ2 from table2));
    mais ça me renvoi une erreur...
    peut-on faire un IN sur plusieurs champs? sinon, y a t il un moyen de contourner le problème?

    @ bientot

  2. #2
    Rédacteur

    Inscrit en
    Septembre 2004
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 626
    Points : 848
    Points
    848
    Par défaut
    Tu y étais presque, tu peux faire comme ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from table1 where (champ1, champ2) IN (select champ1, champ2 from table2);
    Laly.

  3. #3
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    Sinon tu peux faire également une clause exists :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from table1 where exists (select 1 from table2 where table2.champ1 = table1.champ1 and table2.champ2=table1.champ2);
    ...ce qui peut être plus performant...

  4. #4
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    Effectivement, IN doit être évité au profit de EXISTS

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    15
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 15
    Points : 17
    Points
    17
    Par défaut
    D'accord, c'est noté. Je le ferais donc avec la "EXIST"

    Merci pour votre aide précieuse

  6. #6
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    Citation Envoyé par lalystar
    Tu y étais presque, tu peux faire comme ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from table1 where (champ1, champ2) IN (select champ1, champ2 from table2);
    Laly.
    la prochaine fois que je te vois donner la syntaxe du IN, je te colle à taper 100 fois : "je remplacerai le IN par EXISTS dans mes requêtes SQL"


  7. #7
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    Citation Envoyé par Taichin
    D'accord, c'est noté. Je le ferais donc avec la "EXIST"

    Merci pour votre aide précieuse
    pense au tag résolu STP

  8. #8
    Rédacteur

    Inscrit en
    Septembre 2004
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 626
    Points : 848
    Points
    848
    Par défaut
    la prochaine fois que je te vois donner la syntaxe du IN, je te colle à taper 100 fois : "je remplacerai le IN par EXISTS dans mes requêtes SQL"
    Je suis sûr qu'il y a des cas où le IN est plus rapide que le EXIST sinon les deux n'existeraient pas dans Oracle

    J'essaierai de trouver un cas de figure


    Laly.

  9. #9
    CD
    CD est déconnecté
    Membre habitué
    Inscrit en
    Septembre 2004
    Messages
    127
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 127
    Points : 151
    Points
    151
    Par défaut
    Vu sur Asktom pour les différence entre IN et EXISTS :

    http://asktom.oracle.com/pls/ask/f?p...D:953229842074

  10. #10
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 461
    Points : 8 079
    Points
    8 079
    Par défaut
    Citation Envoyé par CD
    Vu sur Asktom pour les différence entre IN et EXISTS :

    http://asktom.oracle.com/pls/ask/f?p...D:953229842074
    Extra ce lien !!!
    Ca prouve une fois de plus qu'il n'y a guère de lois absolues, il faut simplement comprendre ce qu'on fait...

  11. #11
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    mouais... moi je vois surtout que si la table est bien indexée alors le EXISTS reste plus performant même si la volumétrie de la sous-requête est plus importante que dans le IN...(Then the exists will be faster as the time to full scan T1 and do the index probe into T2 could be less then the time to simply full scan T2 to build the subquery we need to distinct on.)

    Mr Kyte oublie aussi le problème de tri dans le cas du IN, puisque qui dit DISTINCT dit tri... or il explique que le IN est intéressant quand les valeurs distinctes permettent d'avoir une volumétrie très réduite... mais dans ce cas le tri est TRES couteux.

    Donc, si le modèle est bon, le EXISTS est meilleur... d'abord j'ai raison

  12. #12
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    il s'agit aussi de faire le EXISTS dans le bon sens :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT * FROM small_tab 
    WHERE EXISTS (SELECT 1 FROM big_tab WHERE...)
    puisque la 1° partie fait un FULL SCAN...

    Le IN est plus intéressant seulement si TOUTES les valeurs de la sous-requête comptent...

    EXISTS, comme son nom l'indique, est intéressant dans les tests d'existence

  13. #13
    CD
    CD est déconnecté
    Membre habitué
    Inscrit en
    Septembre 2004
    Messages
    127
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 127
    Points : 151
    Points
    151
    Par défaut
    Ce que j'en ai compris entre autre, c'est lors de l'évalutation du chemin d'exécution, la requête principale différait en fonction du IN et du EXISTS :
    - EXISTS : La requête principale utilisée pour le plan d'exécution est la requête générale (celle qui appelle le EXISTS)
    - IN : La requête principale sur laquelle se base l'optimiseur est la sous-requête donnée par le IN.

    Citation Envoyé par MrKyte
    after running it -- i verified it and the "rule of thumb" holds true. BIG outer query and SMALL inner query = IN. SMALL outer query and BIG inner query = WHERE EXISTS. Remember -- thats is a RULE OF THUMB and rules of thumb always have infinitely many exceptions to the rule.
    Mais de toute façon, c'est aussi vrai que dans la plupart des cas, le EXISTS est plus rapide que le IN...

  14. #14
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    Citation Envoyé par CD
    - IN : La requête principale sur laquelle se base l'optimiseur est la sous-requête donnée par le IN.
    oui, et en principe le nombre de ligne est plus petit ce qui limite le nombre de tests... mais c'est sans tenir compte des jointures du EXISTS qui peuvent non seulement restreindre le volume mais surtout filtrer sur les seules lignes utiles

  15. #15
    Candidat au Club
    Inscrit en
    Juin 2003
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    je modifie la requête qui est un peu longue (avec plusieurs IN) et je te tiens au courant des résultats.

  16. #16
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    ça marche

  17. #17
    Membre du Club
    Inscrit en
    Avril 2004
    Messages
    54
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 54
    Points : 65
    Points
    65
    Par défaut
    Citation Envoyé par lalystar
    la prochaine fois que je te vois donner la syntaxe du IN, je te colle à taper 100 fois : "je remplacerai le IN par EXISTS dans mes requêtes SQL"
    Je suis sûr qu'il y a des cas où le IN est plus rapide que le EXIST sinon les deux n'existeraient pas dans Oracle
    J'essaierai de trouver un cas de figure
    Laly.
    Hors sujet d'accord

    Le constat de Laly se vérifie également sous DB2

    Le jour ou je m'en suis rendu compte, un paquet de certitudes ont volé en éclat

  18. #18
    Candidat au Club
    Inscrit en
    Juin 2003
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    J'ai modifié la requête suivante mais j'ail'impression qu'elle mouline.
    je ne comprends pas ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    UPDATE S23_USE_BREAKDOWN S23UB
    SET
    S23UB.SUBR_AT_CALLS=0, S23UB.SUBR_AT_DURATION=0,
    S23UB.SUBR_AT_UNITS=0, S23UB.SUBR_AT_VOLUME=0,
    S23UB.SUBR_AT_COSTIC=0, S23UB.SUBR_AT_COSTWS=0,
    S23UB.SUBR_AT_COSTRT=0, S23UB.SUBR_AT_COSTDC=0
    WHERE s23ub.pt_partition = 1
    AND EXISTS
        ( SELECT NULL
            FROM s23_usage s23u
            WHERE s23u.pt_partition = 1 AND s23u.s23_at_key = s23ub.s23_at_key
          AND s23ub.usag_id = s23u.usag_id
            AND ( s23u.subr_at_swoff >= ( SELECT add_months(cc.cust_next_inv_date,to_number(substr(cc.cust_bill_key,1,2))*-1)
                                                                       FROM ftrprod_us1.co_customers cc
                                                                      WHERE cc.cust_number = s23u.cust_number )
                         OR s23u.subr_at_swoff = to_date('17-NOV-1858', 'DD-MON-YYYY')  )  
           )
      AND ( EXISTS (SELECT  NULL
                                    FROM s23_subscriber_changes s23sc,
                                    s23_call_alloc_run_nos s23rn
                                    WHERE s23rn.pt_partition = 1
                            AND s23sc.cust_number = s23ub.cust_number
                            AND s23sc.s23_subscriber = s23ub.cust_number
                                    AND s23sc.pt_partition = s23rn.pt_partition)
     
                     OR EXISTS (SELECT NULL
                                FROM s23_subscriber_changes s23sc1,
                                               s23_call_alloc_run_nos s23rn1
                                               WHERE s23rn1.pt_partition = 1
                                    AND s23ub.usag_id  = s23sc1.subc_new_usag_id
                                               AND s23sc1.pt_partition = s23rn1.pt_partition)
                      );

  19. #19
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    c'est horrible

    bon, j'regarde ça

  20. #20
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    j'ai juste reformaté, c'est bien ça la requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    UPDATE S23_USE_BREAKDOWN S23UB
    SET
    S23UB.SUBR_AT_CALLS=0, S23UB.SUBR_AT_DURATION=0,
    S23UB.SUBR_AT_UNITS=0, S23UB.SUBR_AT_VOLUME=0,
    S23UB.SUBR_AT_COSTIC=0, S23UB.SUBR_AT_COSTWS=0,
    S23UB.SUBR_AT_COSTRT=0, S23UB.SUBR_AT_COSTDC=0
    WHERE s23ub.pt_partition = 1
    AND EXISTS
        ( SELECT NULL
            FROM s23_usage s23u
            WHERE s23u.pt_partition = 1 AND s23u.s23_at_key = s23ub.s23_at_key
          AND s23ub.usag_id = s23u.usag_id
            AND ( s23u.subr_at_swoff >= ( SELECT add_months(cc.cust_next_inv_date,to_number(substr(cc.cust_bill_key,1,2))*-1)
                                            FROM ftrprod_us1.co_customers cc
                                           WHERE cc.cust_number = s23u.cust_number 
                                         )
                         OR s23u.subr_at_swoff = to_date('17-NOV-1858', 'DD-MON-YYYY')  
                ) 
         )
    AND EXISTS 
        ( SELECT  NULL
            FROM s23_subscriber_changes s23sc,
                 s23_call_alloc_run_nos s23rn
           WHERE s23rn.pt_partition = 1
             AND s23sc.cust_number = s23ub.cust_number
             AND s23sc.s23_subscriber = s23ub.cust_number
             AND s23sc.pt_partition = s23rn.pt_partition
        )
    OR EXISTS 
       ( SELECT NULL
           FROM s23_subscriber_changes s23sc1,
                s23_call_alloc_run_nos s23rn1
          WHERE s23rn1.pt_partition = 1
            AND s23ub.usag_id  = s23sc1.subc_new_usag_id
            AND s23sc1.pt_partition = s23rn1.pt_partition)
       );

    je me suis pas trompé ?

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 0
    Dernier message: 23/06/2011, 11h28
  2. requete SQl avec la fonction max () qui ne marche pas
    Par eclipse012 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 09/11/2006, 14h32
  3. Problème avec la fonction créer requete de la FAQ
    Par greg64 dans le forum Access
    Réponses: 8
    Dernier message: 28/03/2006, 12h28
  4. Réponses: 2
    Dernier message: 02/12/2005, 10h53
  5. [Requete SQL en VBA] Problème avec la fonction FLOOR
    Par zubral dans le forum Langage SQL
    Réponses: 4
    Dernier message: 13/07/2004, 13h24

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