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

Langage SQL Discussion :

UNION agit comme UNION ALL


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Décembre 2006
    Messages : 50
    Points : 50
    Points
    50
    Par défaut UNION agit comme UNION ALL
    Bonjour,

    J'ai reçu une requête que je dois débugger. Elle affiche tout simplement des doublons. La conséquence c'est que le montant calculé qui nus interesse est doublé.
    Que fait la requête, elle calcule sur la base d'un taux horaire et d'un nombre d'heures le montant dû à un consultant.
    J'ai enlevé de la requête des élements du Select pour ne conserver que celui qui fait que lorsqu'il est dans la liste, j'obtiens 2 lignes au lieu d'une.

    C'est l'élément TAUX. Il est sélectionné de deux manières différentes dans chacun des UNION.

    Dans la première partie de l'union, il vient d'une sous requête, alors dans la 2ème partie de l'union, il vient d'une table.

    Les chiffres sont exactement les mêmes. Exemple, pour le taux horaire d'une personne X qui est 35 par exemple.

    Est-ce qu'Oracle considère que les 2 lignes ramenées ne sont pas égales pour me les afficher ?

    La requête donne des maux de tê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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    SELECT 
            UTEV.TAUX_HOR_REEL TAUX_HORAIRE   
    FROM (SELECT ID_EMPLOYE, TYPE_EMPLOYE,FORFAITAIRE, 
                 MIN(DATE_DEBUT) AS DATE_DEBUT, 
                 MAX(NVL(DATE_FIN,SYSDATE)) AS DATE_FIN 
          FROM UTL_ASSOC_EMPL_DRI 
          GROUP BY ID_EMPLOYE, FORFAITAIRE, TYPE_EMPLOYE) EDRI,
                   GPB_CATGR_PROJ CATP, UTL_PROJ PROJ,                  
                   UTL_FEUIL_TEMPS UFT, GRI_EMPLOYE GEMP,                  
                   GPB_DEMAND DEMA,GPB_ENGGMN ENGG,       
                   GPB_ENGGMN_ITEM ENGI,GPB_FOURNS FOUR,  
                  (SELECT SENGGMN.ID_ENGGMN, SFORF.DATE_DEBUT,SFORF.DATE_FIN,                        
                          SFORF.MNT_FORFAIT MNT_FORFAIT,
                          SFORF.MNT_FORFAIT / (SFORF.DATE_FIN - SFORF.DATE_DEBUT + 1) 
                                            * (LEAST (:P12,SFORF.DATE_FIN) 
                                                - GREATEST(:P11,SFORF.DATE_DEBUT)+ 1)
                                            / SUM(SUFT.NBR_HEURE) AS TAUX_HOR_REEL
                   FROM GPB_MNT_FORFAIT SFORF,     
                        GPB_ENGGMN_ITEM SENGITEM,
                        GPB_ENGGMN SENGGMN,         
                        GPB_DEMAND SDEMAN,
                        UTL_FEUIL_TEMPS SUFT
                   WHERE SDEMAN.ID_FOURNS = :P10
                   AND SDEMAN.FORFAITAIRE ='O'
                   AND SENGGMN.ID_DEMAND = SDEMAN.ID_DEMAND
                   AND SFORF.ID_ENGGMN = SENGGMN.ID_ENGGMN
                   AND SENGGMN.NO_ENGGMN LIKE :P13
                   AND (SFORF.DATE_DEBUT BETWEEN :P11 AND :P12
                       OR SFORF.DATE_FIN BETWEEN :P11 AND :P12
                       OR :P11 BETWEEN SFORF.DATE_DEBUT AND SFORF.DATE_FIN
                       OR :P12 BETWEEN SFORF.DATE_DEBUT AND SFORF.DATE_FIN)
                   AND SENGITEM.ID_ENGGMN = SENGGMN.ID_ENGGMN 
                   AND SENGITEM.ID_EMPLOYE = SUFT.ID_EMPLOYE
                   AND SUFT.DATE_DEBUT BETWEEN GREATEST(:P11,SFORF.DATE_DEBUT, NVL(SENGITEM.DATE_DEBUT,:P11))
                                                  AND LEAST (:P12,SFORF.DATE_FIN,NVL(SENGITEM.DATE_FIN,:P12))
                   AND SUFT.ID_PROJ <> '0'
                   GROUP BY 
                           SENGGMN.ID_ENGGMN,            
                           SFORF.DATE_DEBUT,
                           SFORF.DATE_FIN,               
                           SFORF.MNT_FORFAIT) UTEV   --
    WHERE UFT.ID_PROJ <> '0' -- EMPLOYEE POUR PéRIODE SANS LE PROJET 0  
     AND UFT.DATE_DEBUT BETWEEN :P11 AND :P12 
     AND UFT.ID_EMPLOYE = GEMP.ID_EMPLOYE 
     AND EDRI.ID_EMPLOYE = UFT.ID_EMPLOYE
     AND (:P11  BETWEEN EDRI.DATE_DEBUT AND NVL(EDRI.DATE_FIN,:P12)
                 OR :P12  BETWEEN EDRI.DATE_DEBUT AND NVL(EDRI.DATE_FIN,:P12)) 
     AND EDRI.TYPE_EMPLOYE  <> 'RE' 
     AND UFT.ID_PROJ = PROJ.ID_PROJ -- LA CATEGORIE DE PROJET 
     AND PROJ.ID_CATGR_PROJ = CATP.ID_CATGR_PROJ  
     AND FOUR.ID_FOURNS = :P10  -- FOURNISSEUR SéLECTIONNé 
     AND DEMA.ID_FOURNS = FOUR.ID_FOURNS-- DEMANDE  POUR PéRIODES ET FOURN  
     AND UFT.DATE_DEBUT BETWEEN NVL(DEMA.DATE_DEBUT,:P11)  AND NVL(DEMA.DATE_FIN, :P12)
     AND ENGG.ID_DEMAND = DEMA.ID_DEMAND -- ENGAGEMENTS PéRIODE ET DEMANDE
     AND ENGG.NO_ENGGMN LIKE :P13
     AND UFT.DATE_DEBUT BETWEEN NVL(ENGG.DATE_DEBUT, NVL(DEMA.DATE_DEBUT,:P11))
                              AND NVL(ENGG.DATE_FIN, NVL(DEMA.DATE_FIN,  :P12))
     AND UFT.DATE_DEBUT BETWEEN NVL(ENGG.DATE_DEBUT, NVL(DEMA.DATE_DEBUT,:P11)) 
                              AND NVL(ENGG.DATE_FIN, NVL(DEMA.DATE_FIN,  :P12)) 
     AND UTEV.ID_ENGGMN = ENGG.ID_ENGGMN --LE TAUX HORAIRE SELON LE FORFAIT 
     AND UFT.DATE_DEBUT BETWEEN UTEV.DATE_DEBUT AND NVL(UTEV.DATE_FIN,UFT.DATE_DEBUT)
     AND ENGI.ID_ENGGMN = ENGG.ID_ENGGMN 
     AND ENGI.ID_EMPLOYE = UFT.ID_EMPLOYE 
     AND UFT.DATE_DEBUT BETWEEN NVL(ENGI.DATE_DEBUT,NVL(ENGG.DATE_DEBUT, NVL(DEMA.DATE_DEBUT,:P11))) 
                                  AND NVL(ENGI.DATE_FIN,NVL(ENGG.DATE_FIN, NVL(DEMA.DATE_FIN,:P12)))  
    GROUP BY :P11, :P12, UTEV.ID_ENGGMN, FOUR.NOM_FOURNS, DEMA.NO_DEMAND, UFT.ID_PROJ,  
             GEMP.NOM || ',' || GEMP.PRENOM || DECODE(EDRI.FORFAITAIRE,'O','(FORFAITAIRE)',''),
             UTEV.TAUX_HOR_REEL, CATP.ID_CATGR_PROJ, CATP.DESC_CATGR_PROJ                                                                                      
    UNION 
    --TEMPS HORAIRE NON-FORFAITAIRE 
    SELECT  
         UAED.TAUX_HOR_REEL TAUX_HORAIRE        
    FROM UTL_ASSOC_EMPL_DRI UAED,GPB_CATGR_PROJ GCP, UTL_PROJ UP,     
         UTL_FEUIL_TEMPS UFT, GRI_EMPLOYE GE, GPB_ENGGMN_ITEM GEI,    
         GPB_ENGGMN ENGG,GPB_DEMAND DEMA, GPB_FOURNS FOUR            
    WHERE UFT.DATE_DEBUT BETWEEN :P11 AND :P12-- PÉRIODE SANS PROJET 0 
     AND UFT.ID_PROJ <> '0' 
     AND UFT.ID_PROJ = UP.ID_PROJ  -- TROUVER LA CATEGORIE DE PROJET 
     AND UP.ID_CATGR_PROJ = GCP.ID_CATGR_PROJ 
     AND UFT.ID_EMPLOYE = GE.ID_EMPLOYE -- LES EMPLOYE CONSULTANT PÉRIODE 
     AND UFT.ID_EMPLOYE = UAED.ID_EMPLOYE 
     AND UAED.TYPE_EMPLOYE  <> 'RE'          
     AND UAED.FORFAITAIRE = 'N' 
     AND UFT.DATE_DEBUT BETWEEN UAED.DATE_DEBUT AND NVL(UAED.DATE_FIN,:P12) 
     AND FOUR.ID_FOURNS = :P10    -- POUR LE FOURNISSEUR SÉLECTIONNÉ  
     AND DEMA.ID_FOURNS = FOUR.ID_FOURNS-- LES DEMANDES DANS LA PÉRIODES 
     AND UFT.DATE_DEBUT BETWEEN NVL(DEMA.DATE_DEBUT,:P11)  AND NVL(DEMA.DATE_FIN,:P12) 
     AND ENGG.ID_DEMAND = DEMA.ID_DEMAND -- ENGAGEMENTS POUR LA PÉRIODE
     AND ENGG.NO_ENGGMN LIKE :P13 
     AND UFT.DATE_DEBUT BETWEEN NVL(ENGG.DATE_DEBUT, NVL(DEMA.DATE_DEBUT,:P11)) AND NVL(ENGG.DATE_FIN, NVL(DEMA.DATE_FIN,:P12)) 
              -- ITEMS D'ENGAGEMENT POUR LES EMPLOYE ET LA PÉRIODE 
     AND GEI.ID_ENGGMN = ENGG.ID_ENGGMN 
     AND GEI.ID_EMPLOYE = UFT.ID_EMPLOYE 
     AND UFT.DATE_DEBUT BETWEEN NVL(GEI.DATE_DEBUT,NVL(ENGG.DATE_DEBUT,NVL(DEMA.DATE_DEBUT,:P11))) 
                                  AND NVL(GEI.DATE_FIN,NVL(ENGG.DATE_FIN,NVL(DEMA.DATE_FIN,:P12)))
     AND :P11 <= NVL(GEI.DATE_FIN,NVL(ENGG.DATE_FIN,NVL(DEMA.DATE_FIN,:P12)))
     GROUP BY :P12, :P11, FOUR.NOM_FOURNS, DEMA.NO_DEMAND,                      
               GE.NOM || ',' || GE.PRENOM || DECODE(UAED.FORFAITAIRE,'O','(FORFAITAIRE)',''),
               UAED.TAUX_HOR_REEL,UFT.ID_PROJ,GCP.ID_CATGR_PROJ,GCP.DESC_CATGR_PROJ

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    La requête donne des maux de tête
    Si vous l'écriviez de manière normative et que vous l'indentiez, elle vous en donnerait un peu moins.
    Pour la première partie :
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    WITH EDR AS
    (
      SELECT ID_EMPLOYE, TYPE_EMPLOYE, FORFAITAIRE,
             MIN(DATE_DEBUT)                  AS DATE_DEBUT,
             COALESCE(MAX(DATE_FIN), SYSDATE) AS DATE_FIN
       WHERE TYPE_EMPLOYE <> 'RE'
        FROM UTL_ASSOC_EMPL_DRI
    GROUP BY ID_EMPLOYE, TYPE_EMPLOYE, FORFAITAIRE
      HAVING :P11 BETWEEN  MIN(DATE_DEBUT) AND COALESCE(MAX(DATE_FIN), SYSDATE)
          OR :P12 BETWEEN  MIN(DATE_DEBUT) AND COALESCE(MAX(DATE_FIN), SYSDATE)
    )
      ,  UTV AS
    (
    SELECT
        ENG.ID_ENGGMN,
        FRF.DATE_DEBUT,
        FRF.DATE_FIN,
        FRF.MNT_FORFAIT,
        FRF.MNT_FORFAIT
        / (FRF.DATE_FIN - FRF.DATE_DEBUT + 1)
        * (LEAST (:P12, FRF.DATE_FIN) - GREATEST(:P11, FRF.DATE_DEBUT)+ 1)
        / SUM(UFT.NBR_HEURE) AS TAUX_HOR_REEL
    FROM
        GPB_MNT_FORFAIT FRF
        INNER JOIN GPB_ENGGMN ENG
          ON ENG.ID_ENGGMN = FRF.ID_ENGGMN
        INNER JOIN GPB_DEMAND DEM
          ON DEM.ID_DEMAND = ENG.ID_DEMAND
        INNER JOIN GPB_ENGGMN_ITEM ENI
          ON ENI.ID_ENGGMN = ENG.ID_ENGGMN
        INNER JOIN UTL_FEUIL_TEMPS UFT
          ON SUFT.ID_EMPLOYE = ENI.ID_EMPLOYE
    WHERE
        DEM.ID_FOURNS = :P10
    AND DEM.FORFAITAIRE = 'O'
    AND ENG.NO_ENGGMN LIKE :P13
    AND (FRF.DATE_DEBUT BETWEEN :P11 AND :P12
      OR FRF.DATE_FIN   BETWEEN :P11 AND :P12
      OR :P11 BETWEEN FRF.DATE_DEBUT AND FRF.DATE_FIN
      OR :P12 BETWEEN FRF.DATE_DEBUT AND FRF.DATE_FIN)
    AND UFT.DATE_DEBUT BETWEEN GREATEST(:P11, FRF.DATE_DEBUT, COALESCE(ENI.DATE_DEBUT, :P11))
                           AND LEAST   (:P12, FRF.DATE_FIN  , COALESCE(ENI.DATE_FIN  , :P12))
    AND UFT.ID_PROJ <> '0'
    GROUP BY
        ENG.ID_ENGGMN,
        FRF.DATE_DEBUT,
        FRF.DATE_FIN,
        FRF.MNT_FORFAIT
    )
    SELECT
        UTV.TAUX_HOR_REEL AS TAUX_HORAIRE
    FROM
        EDR
        INNER JOIN UTL_FEUIL_TEMPS UFT
          ON UFT.ID_EMPLOYE = EDR.ID_EMPLOYE
        INNER JOIN GRI_EMPLOYE EMP
          ON EMP.ID_EMPLOYE = UFT.ID_EMPLOYE
        INNER JOIN UTL_PROJ PRJ
          ON PRJ.ID_PROJ = UFT.ID_PROJ
        INNER JOIN GPB_CATGR_PROJ CTP
          ON CTP.ID_CATGR_PROJ = PRJ.ID_CATGR_PROJ
        INNER JOIN GPB_ENGGMN_ITEM ENI
          ON ENI.ID_EMPLOYE = UFT.ID_EMPLOYE 
        INNER JOIN GPB_ENGGMN ENG
          ON ENG.ID_ENGGMN = ENI.ID_ENGGMN
        INNER JOIN UTV
          ON UTV.ID_ENGGMN = ENG.ID_ENGGMN
        INNER JOIN GPB_DEMAND DEM
          ON DEM.ID_DEMAND = ENG.ID_DEMAND
        INNER JOIN GPB_FOURNS FOU
          ON FOU.ID_FOURNS = DEM.ID_FOURNS
    WHERE
        UFT.ID_PROJ <> '0'
    AND FOU.ID_FOURNS = :P10
    AND ENG.NO_ENGGMN LIKE :P13
    AND UFT.DATE_DEBUT BETWEEN GREATEST(:P11, COALESCE(DEM.DATE_DEBUT, :P11), COALESCE(ENG.DATE_DEBUT, :P11), UTV.DATE_DEBUT                        , COALESCE(ENI.DATE_DEBUT, :P11))
                           AND LEAST   (:P12, COALESCE(DEM.DATE_FIN  , :P12), COALESCE(ENG.DATE_FIN  , :P12), COALESCE(UTV.DATE_FIN, UFT.DATE_DEBUT), COALESCE(ENI.DATE_FIN  , :P12))
    GROUP BY
        :P11,
        :P12,
        UTV.ID_ENGGMN,
        FOU.NOM_FOURNS,
        DEM.NO_DEMAND,
        UFT.ID_PROJ,  
        EMP.NOM || ',' || EMP.PRENOM || CASE EDR.FORFAITAIRE WHEN 'O' THEN '(FORFAITAIRE)' END,
        UTV.TAUX_HOR_REEL,
        CTP.ID_CATGR_PROJ,
        CTP.DESC_CATGR_PROJ
    J'ai remis vos tables dans un ordre parlant.
    J'ai fusionné vos cinq filtres sur UFT.DATE_DEBUT.
    J'ai remonté quelques critères dans la première CTE.
    J'ai raccourci vos alias de tables : aliaser GPB_ENGGMN en SENGGMN c'est vraiment symbolique et à mon sens ne facilite pas réellement la relecture.

    Rien ne vous choque quand vous regardez le select et le group by ?
    J'ai aussi des doutes sur la formule de calcul du taux horaire réel.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Décembre 2006
    Messages : 50
    Points : 50
    Points
    50
    Par défaut
    Merci,

    J'ai pris du temps pour m'exercer en la clause With que je n'utilise pas, personne dans notre entreprise d'ailleurs.

    En tout réécrivant comme tu l'as fait, c'était plus lisible mais le résultat est pareil, c'est à dire 2 lignes.

    Etant donné que j'avais isolé que c'était le taux dans le Select qui faisait que j'avais 2 lignes, et que celui-ci était retrouvé de 2 manières différentes de par et d'autre de l'UNION, une fois par calcul, l'autre fois d'une table, j'ai pensé que le résultat du calcul devait ramené des chiffres après la virgule. J'ai fait un CAST et tout est bon. J'aurais pû faire autrement aussi.

    Merci, c'est résolu.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [10g] Union ou pas union, tel est la question
    Par Invité dans le forum Débuter
    Réponses: 4
    Dernier message: 16/05/2013, 17h19
  2. touche entrée agit comme un tab
    Par y_marky dans le forum IHM
    Réponses: 1
    Dernier message: 31/03/2012, 00h08
  3. union horizontale et union verticale
    Par Kurisu dans le forum C++
    Réponses: 3
    Dernier message: 12/09/2008, 12h13
  4. ASP URL hyperlien agit comme bouton SUBMIT
    Par hottnikks_79 dans le forum ASP
    Réponses: 2
    Dernier message: 11/08/2006, 21h00
  5. union all couteux ?
    Par Maitre B dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 16/11/2004, 09h26

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