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 :

Somme de 2 requêtes


Sujet :

SQL Oracle

  1. #1
    Nouveau membre du Club
    Femme Profil pro
    chargé d'études statistiques et marketing
    Inscrit en
    Avril 2015
    Messages
    74
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : chargé d'études statistiques et marketing

    Informations forums :
    Inscription : Avril 2015
    Messages : 74
    Points : 32
    Points
    32
    Par défaut Somme de 2 requêtes
    Bonjour

    j'ai besoin d'additionner les lignes de 2 requetes de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    select * from D_offre_com o
    left join d_contrat_permanent p
    on p.numofr_init = o.numofr or p.numofr_der = o.numofr
    where (
    (p.datsor is null
    and o.codsitofr is null
    or o.codsitofr in ('54','57','59'))
    OR
    (o.datstaofr <= add_months('05/01/2023',36)
    and p.datsor is not null))
    +
    select *from D_offre_com where o.numofr not in (p.numofr_init union p.numofr_der)
    je ne sais pas comment on peut faire pour additionner la 2è partie après le + ?

    merci ;-)

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

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Bonjour,
    qu'est-ce que tu entends par "additionner" ?
    Si tu veux que le résultat contienne les lignes des deux requêtes, il faut utilise une UNION:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select ...
    UNION
    select ...
    Et si tu ne veux pas supprimer les doublons, un UNION ALL sera (un peu) plus performant si les deux requêtes renvoient beaucoup de lignes.
    Par contre il faut remplacer les SELECT * par la liste des colonnes à renvoyer dans les deux requêtes, et que les deux listes soient cohérentes. Dans le cas contraire l'union ne fonctionnera pas.

    Si tu veux une addition au sens mathématique, il nous faut plus d'infos (le schéma des tables, un jeu de test et le résultat attendu).

    Tatayo.

  3. #3
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 561
    Points
    38 561
    Billets dans le blog
    9
    Par défaut
    Attention aussi aux combinaisons de AND et OR sans parenthèses : le résultat obtenu ne sera pas forcément celui attendu.
    Ne serait-ce que pour des raisons de lisibilité et de maintenance, il est préférable d'ajouter des parenthèses.

  4. #4
    Membre chevronné
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 138
    Points : 1 918
    Points
    1 918
    Par défaut
    OMG, une date passée en tant que chaines de caractères
    Quand tu passes une valeur date, il faut utiliser TO_DATE pour éviter une conversion implicite.

    Dans ton exemple, si le format nls date par défaut est mm/dd/yyyy, alors il s'agira du 1er mai 2023. Donc si tu veux que ce soit le 5 janvier 2023, précise-le explicitement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    add_months(to_date('05/01/2023', 'dd/mm/yyyy'),36)
    Sinon pour ton besoin, j'ai l'impression que tu peux juste ajouter une condition.

  5. #5
    Nouveau membre du Club
    Femme Profil pro
    chargé d'études statistiques et marketing
    Inscrit en
    Avril 2015
    Messages
    74
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : chargé d'études statistiques et marketing

    Informations forums :
    Inscription : Avril 2015
    Messages : 74
    Points : 32
    Points
    32
    Par défaut
    Merci pour vos réponses

    oui c'était pour ajouter les lignes


    par contre, je me rends compte que ma requête tourne très longtemps
    est-ce qu'on peut écrire cette requête de manière plus performante d'après vous ?
    rappel ci-dessous de la requête où j'ai modifié un OR par un AND correspondant à ce que je cherche

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    select * from D_offre_com o
    left join d_contrat_permanent p
    on p.numofr_init = o.numofr or p.numofr_der = o.numofr
    where (
    (p.datsor is null
    and o.codsitofr is null
    or o.codsitofr in ('54','57','59'))
    and 
    (o.datstaofr <= add_months('05/01/2023',36)
    and p.datsor is not null)
    );

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Sans connaitre la structure des tables, les éventuels indexes, sans le plan d'exécution, il est difficile pour nous de répondre.

    Tatayo.

  7. #7
    Nouveau membre du Club
    Femme Profil pro
    chargé d'études statistiques et marketing
    Inscrit en
    Avril 2015
    Messages
    74
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : chargé d'études statistiques et marketing

    Informations forums :
    Inscription : Avril 2015
    Messages : 74
    Points : 32
    Points
    32
    Par défaut
    comment svp utilise-t-on les indexes ?

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Tu as toutes les infos ici.

    Tatayo

  9. #9
    Nouveau membre du Club
    Femme Profil pro
    chargé d'études statistiques et marketing
    Inscrit en
    Avril 2015
    Messages
    74
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : chargé d'études statistiques et marketing

    Informations forums :
    Inscription : Avril 2015
    Messages : 74
    Points : 32
    Points
    32
    Par défaut
    merci
    j'ai compris que ça accélérait mais pas comment je l'écrit en requête

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Bonjour,
    On n'utilise pas un index dans une requête, c'est le moteur (ici Oracle) qui va décider ou pas d'utiliser tel ou tel index, en fonction de la requête (colonnes renvoyées, jointures, colonnes filtrées, type de filtre...).
    Ici comme on ne connait ni la structure des tables, ni les indexes existants, on ne peut pas te dire comment optimiser ta requête.

    Accessoirement comme l'indiquait escartefigue, tu as une combinaison de AND et de OR sans parenthèse, donc il existe un risque que le résultat renvoyé ne soit pas celui attendu:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    p.datsor is null
    and o.codsitofr is null
    or o.codsitofr in ('54','57','59')
    Est-ce qu'il faut compendre:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    (p.datsor is null
    and o.codsitofr is null)
    or o.codsitofr in ('54','57','59')
    Ou:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    p.datsor is null
    and
    (o.codsitofr is null or o.codsitofr in ('54','57','59'))

    Tatayo.

  11. #11
    Nouveau membre du Club
    Femme Profil pro
    chargé d'études statistiques et marketing
    Inscrit en
    Avril 2015
    Messages
    74
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : chargé d'études statistiques et marketing

    Informations forums :
    Inscription : Avril 2015
    Messages : 74
    Points : 32
    Points
    32
    Par défaut
    bonjour
    oui merci j'ai bien mis les () comme suit de mon côté

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    p.datsor is null
    and
    (o.codsitofr is null or o.codsitofr in ('54','57','59'))
    index de la d_offre_com :
    REF IDX_REF_D_OFFRE_COM Unique TRAORI, NUMOFR, DEBVLE N N tablespace ref_indx pctfree 10 initrans 2 maxtrans 255 storage ( initial 169600k next 1m minextents 1 maxextents unlimited )
    REF PK_REF_D_OFFRE_COM Unique IDTOFR N N tablespace ref_indx pctfree 10 initrans 2 maxtrans 255 storage ( initial 26432k next 1m minextents 1 maxextents unlimited )
    REF PK_REF_D_OFFRE_COM_NUMCON Normal NUMCON N N tablespace ref_indx pctfree 10 initrans 2 maxtrans 255 storage ( initial 34m next 1m minextents 1 maxextents unlimited )

    et d_contrat_permanent :

    REF IDX_CONTP_1 Normal NUMCON, FAMIFP, IDTPRT, DATTRM N N tablespace ref_indx pctfree 10 initrans 2 maxtrans 255 storage ( initial 370240k next 1m minextents 1 maxextents unlimited )
    REF IDX_CONTP_2 Normal NUMCON, IDTPRT, FAMIFP N N tablespace ref_indx pctfree 10 initrans 2 maxtrans 255 storage ( initial 344000k next 1m minextents 1 maxextents unlimited )
    REF IDX_CONTP_3 Normal NUMCON, FAMIFP, IDTPRT, DATEFF N N tablespace ref_indx pctfree 10 initrans 2 maxtrans 255 storage ( initial 424m next 1m minextents 1 maxextents unlimited )
    REF IDX_NUMAGTREA Normal NUMAGT_AGTREA, FLG_GENERENVCLI N N tablespace ref_indx pctfree 10 initrans 2 maxtrans 255 storage ( initial 240m next 1m minextents 1 maxextents unlimited )
    REF PK_REF_D_CONTRAT_PERMANENT Unique NUMCON N N tablespace ref_indx pctfree 10 initrans 2 maxtrans 255 storage ( initial 256960k next 1m minextents 1 maxextents unlimited )

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Du coup je me demande bien comment ta requête peut renvoyer des données:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    select * from D_offre_com o
    left join d_contrat_permanent p
    on p.numofr_init = o.numofr or p.numofr_der = o.numofr
    where (
    (p.datsor is null
    and (o.codsitofr is null
    or o.codsitofr in ('54','57','59')))
    and 
    (o.datstaofr <= add_months('05/01/2023',36)
    and p.datsor is not null)
    );
    Si je supprime les parenthèses "inutiles" du point de vue logique booléenne ( A and (B and C) équivaut à A AND B AND C et a (A and B) and C) et que je change l'ordre des filtres (le AND est commutatif), on a la restriction suivante:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    select * from D_offre_com o
    left join d_contrat_permanent p
    on p.numofr_init = o.numofr or p.numofr_der = o.numofr
    where (
    p.datsor is null
    and p.datsor is not null
    and o.datstaofr <= add_months('05/01/2023',36)
    and (o.codsitofr is null
    or o.codsitofr in ('54','57','59'))
    p.datsor doit être null et non null en même temps, ça ne peut pas fonctionner !

    Tatayo.

  13. #13
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    A première vue la condition du WHERE telle qu'écrite est équivalente à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    o.codsitofr in ('54','57','59')
    and o.datstaofr <= add_months('05/01/2023',36)
    and p.datsor is not null
    changer la première partie en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ((p.datsor is null
    and o.codsitofr is null)
    or o.codsitofr in ('54','57','59'))
    ne changerait donc rien du tout.

  14. #14
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Je viens de voir la description des indexes:
    • Pour la table D_offre_com, aucun n'a comme première colonne codsitofr ou datstaofr qui sont utilisées comme filtre ou numofr utilisée pour la jointure.
    • Pour la table d_contrat_permanent, aucun n'a comme première colonne numofr_der, qui est utilisé pour la jointure

    Donc aucun index n'est utilisable ici, que ce soit pour filtrer les tables ou pour la jointure.
    De fait Oracle est obligé de lire toutes les lignes des deux tables pour retrouver ses petits.
    Enfin un SELECT * empêche d'utiliser un éventuel index couvrant.

    Je ne connais pas trop Oracle, mais tu devrais regarder le plan d'exécution de la requête, peut-être qu'il t'indiquera quel indexes devraient être ajoutés sur les deux tables pour améliorer le temps d'exécution de la requête.

    Tatayo.

  15. #15
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 561
    Points
    38 561
    Billets dans le blog
    9
    Par défaut
    @Bichette001

    Comme je le disais plus haut, en l'absence de parenthèses, les combinaisons d'opérateurs AND et OR ne produisent pas toujours les résultats attendus, dans votre nouvelle réponse n° 5, on a toujours ce même problème.

    A and B or C

    Ne produit pas le même résultat que

    A and (B or C)

  16. #16
    Nouveau membre du Club
    Femme Profil pro
    chargé d'études statistiques et marketing
    Inscrit en
    Avril 2015
    Messages
    74
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : chargé d'études statistiques et marketing

    Informations forums :
    Inscription : Avril 2015
    Messages : 74
    Points : 32
    Points
    32
    Par défaut
    merci pour ta remarque

    pour les indexes si les champs que tu cites avaient été des index=> pas de modif pour le script de ma requête , c'est ce que tu dis ?
    où peut-on trouver le plan d'exécution de requête?

    pour les (), si je mets A and (B or C) sous-entend A et (codsitofr est null ou = 54 ou = 57 ou = 59)
    tu l'écrirais comment ?

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Pour le plan d'exécution, une recherche rapide dans Google m'a donné ceci.

    Concernant l'écriture de la requête (parenthèses et autre), sans jeu de test et résultat attendu, la seule réponse que tu peux avoir est: aucune idée.

    Tatayo.

  18. #18
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 561
    Points
    38 561
    Billets dans le blog
    9
    Par défaut
    Cette condition qui présente des parenthèses inutiles alors que d'autres parenthèses manquent :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    where (    (    p.datsor is null
                and o.codsitofr is null
                or o.codsitofr in ('54','57','59'))
                and 
               ( o.datstaofr <= add_months('05/01/2023',36)
                  and p.datsor is not null)
          )
    ;

    est à remplacer par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    where p.datsor is null
      and (    o.codsitofr is null
           or  o.codsitofr in ('54','57','59')
          )
      and o.datstaofr <= add_months('05/01/2023',36)
      and p.datsor is not null
    ;
    Le plan d'exécution peut être estimé grâce à un EXPLAIN ou vérifié avec DBMS_XPLAN.
    Attention : une estimation (EXPLAIN) ne vaut que pour la plate-forme d'exécution sur laquelle elle est calculée. Comme le calcul se base essentiellement sur les statistiques et les index, deux plates formes différentes peuvent produire des estimations différentes (les index installés, les cardinalités, les dates de dernières réorg... peuvent être différents entre par exemple une production et un environnement de recette).

  19. #19
    Nouveau membre du Club
    Femme Profil pro
    chargé d'études statistiques et marketing
    Inscrit en
    Avril 2015
    Messages
    74
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : chargé d'études statistiques et marketing

    Informations forums :
    Inscription : Avril 2015
    Messages : 74
    Points : 32
    Points
    32
    Par défaut
    le explain semble intéressant
    je dois l'écrire comment ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     explain select * from d_offre_com;
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     explain plan select * from d_offre_com;
    ces 2 scripts ne fonctionnent pas ..🤨

  20. #20
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    explain plan for
    select ...
    ;
     
    SELECT * FROM table(DBMS_XPLAN.DISPLAY);
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    select * from dbms_xplan.display_cursor(null, null, 'ALLSTATS LAST') ;
    -- il faut le "SELECT privilege on V$SESSION"

Discussions similaires

  1. [AC-2003] somme conditionnelle dans requête de synthèse
    Par yupyupxav dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 04/02/2010, 19h40
  2. Opérations "Regroupement" et "Somme" dans les requêtes
    Par louisbru dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 27/02/2009, 19h29
  3. [A-03] Somme dans une requête
    Par mathilde50 dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 07/11/2008, 17h57
  4. Calcul d'une différence de sommes dans une requête
    Par oohcalme dans le forum Requêtes et SQL.
    Réponses: 12
    Dernier message: 07/07/2008, 11h56
  5. Somme de deux requête en une en sql/access
    Par thepunky89 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 13/09/2007, 14h31

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