Requête : Union de 2 Requête ... Difficile

Ish
Eléphant du PHP | 200 Messages

24 août 2007, 16:20

Bonjour à tous ...

je bloque depuis tout à l'heure sur une grosse requête SQL
J'ai deux requête qui ne sont différente que par une variable

je voudrais le réunir pour obtenir un tableau avec des dates qui fusionnent et les autres champs !! (confus) !

Code : Tout sélectionner

SELECT FINISHDATE, sum(NB_OT) AS NB_Y1, sum(DUREE_REAL) AS DUREE_Y1 FROM ( SELECT TO_CHAR(kp1.FINISHDATE,'YYYY-MM') AS FINISHDATE, kp1.NB_OT,kp1.DUREE_REAL FROM SDNI.SDNQTKP1 kp1 WHERE kp1.PLANPLANT='CCA1' AND (kp1.FUNCT_LOC LIKE '?010%') AND (nvl(kp1.STATUTA1,'Z')<>'ANNU' OR nvl(kp1.STATUTA2,'Z')<>'ANNU' OR nvl(kp1.STATUTA3,'Z')<>'ANNU') AND (COORD_TYPE IN ('ZURG') AND PMACTTYPE IN ('PAL','CUR')) AND ( TO_CHAR(kp1.FINISHDATE,'YYYY-MM')>=to_char(to_date('03/01/2006'),'YYYY-MM') and TO_CHAR(kp1.FINISHDATE,'YYYY-MM')<=to_char(to_date('31/07/2008'),'YYYY-MM') ) ) GROUP BY FINISHDATE
Qui me ramène un tableau ...de type
Date | NB_Y1 | DUREE_Y1

Code : Tout sélectionner

SELECT FINISHDATE, sum(NB_OT) AS NB_Y2, sum(DUREE_REAL) AS DUREE_Y2 FROM ( SELECT TO_CHAR(kp1.FINISHDATE,'YYYY-MM') AS FINISHDATE, kp1.NB_OT , kp1.DUREE_REAL FROM SDNI.SDNQTKP1 kp1 WHERE kp1.PLANPLANT='CCA1' AND (kp1.FUNCT_LOC LIKE '?010%') AND (nvl(kp1.STATUTA1,'Z')<>'ANNU' OR nvl(kp1.STATUTA2,'Z')<>'ANNU' OR nvl(kp1.STATUTA3,'Z')<>'ANNU') AND (COORD_TYPE IN ('ZPRE','ZREG') AND PMACTTYPE IN ('SYS','CON','PRE','ESY')) AND ( TO_CHAR(kp1.FINISHDATE,'YYYY-MM')>=to_char(to_date('03/01/2006'),'YYYY-MM') and TO_CHAR(kp1.FINISHDATE,'YYYY-MM')<=to_char(to_date('31/07/2008'),'YYYY-MM') ) ) GROUP BY FINISHDATE
qui me ramène un tableau de type
DATE | NB_Y2 | DUREE_Y2


Ce que je voudrais faire c'est avoir un tableau de type
DATE | NB_Y1 | DUREE_Y1 | NB_Y2 | DUREE_Y2

et si il n'y a pas de résultat pour l'une des deux requête, mettre le champ (Y1 ou Y2) à 0 !!

C'est assez compliqué et je me demande s'il ne va pas falloir utiliser du PL/SQL
La vie est faite d'imprevu, et l'imprevu fait la vie
Gardez la peche !!

ViPHP
ViPHP | 5924 Messages

24 août 2007, 16:22

Pourquoi ne veux tu pas utiliser la même colonne pour les 2 ?

Eléphant du PHP | 193 Messages

24 août 2007, 17:21

Solution simple, mais lourde:

Code : Tout sélectionner

SELECT FINISHDATE, sum(NB_OT) AS NB_Y1, sum(DUREE_REAL), 0 as NB_Y2, 0 as DUREE_Y2 FROM ... UNION SELECT FINISHDATE, 0, 0, sum(NB_OT), sum(DUREE_REAL) FROM
Là, tu as une ou deux lignes par FINISHDATE, donc il faut encore que tu fasses un GROUP BY pour n'avoir que ta ligne. Je suis quand même à peu près sûr qu'il y a beaucoup mieux.

Ish
Eléphant du PHP | 200 Messages

24 août 2007, 17:32

Pourquoi ne veux tu pas utiliser la même colonne pour les 2 ?
parcequ'elle ne me renvoit pas le même résultat !!!

Bon ... je me suis creusé la tête, j'ai roublardisé et voilà le résultat. Cela me donne ce que je voulais !!


Code : Tout sélectionner

select * from( SELECT FINISHDATE, sum(NB_Y1), sum(NB_Y2), sum(DUREE_Y1), sum(DUREE_Y2) FROM ( (SELECT FINISHDATE, sum(NB_OT) AS NB_Y1, sum(0) AS NB_Y2, sum(DUREE_REAL) AS DUREE_Y1,sum(0) AS DUREE_Y2 FROM ( SELECT TO_CHAR(kp1.FINISHDATE,'YYYY-MM') AS FINISHDATE, kp1.NB_OT,kp1.DUREE_REAL FROM SDNI.SDNQTKP1 kp1 WHERE kp1.PLANPLANT='CCA1' AND (kp1.FUNCT_LOC LIKE '?010%') AND (nvl(kp1.STATUTA1,'Z')<>'ANNU' OR nvl(kp1.STATUTA2,'Z')<>'ANNU' OR nvl(kp1.STATUTA3,'Z')<>'ANNU') AND (COORD_TYPE IN ('ZURG') AND PMACTTYPE IN ('PAL','CUR')) AND ( TO_CHAR(kp1.FINISHDATE,'YYYY-MM')>=to_char(to_date('03/01/2006'),'YYYY-MM') and TO_CHAR(kp1.FINISHDATE,'YYYY-MM')<=to_char(to_date('31/07/2008'),'YYYY-MM') ) ) GROUP BY FINISHDATE) UNION (SELECT FINISHDATE, sum(0) AS NB_Y1,sum(NB_OT) AS NB_Y2, sum(0) AS DUREE_Y1,sum(DUREE_REAL) AS DUREE_Y2 FROM ( SELECT TO_CHAR(kp1.FINISHDATE,'YYYY-MM') AS FINISHDATE, kp1.NB_OT , kp1.DUREE_REAL FROM SDNI.SDNQTKP1 kp1 WHERE kp1.PLANPLANT='CCA1' AND (kp1.FUNCT_LOC LIKE '?010%') AND (nvl(kp1.STATUTA1,'Z')<>'ANNU' OR nvl(kp1.STATUTA2,'Z')<>'ANNU' OR nvl(kp1.STATUTA3,'Z')<>'ANNU') AND (COORD_TYPE IN ('ZPRE','ZREG') AND PMACTTYPE IN ('SYS','CON','PRE','ESY')) AND ( TO_CHAR(kp1.FINISHDATE,'YYYY-MM')>=to_char(to_date('03/01/2006'),'YYYY-MM') and TO_CHAR(kp1.FINISHDATE,'YYYY-MM')<=to_char(to_date('31/07/2008'),'YYYY-MM') ) ) GROUP BY FINISHDATE) ) group by FINISHDATE ORDER BY FINISHDATE ) WHERE ROWNUM <= 10
En fait je fais une union deux requête, puis je fais une sum de colonne Group by la date ...
Là où j'ai roublardisé .. c'est que dans ma première requête .. je met Nb_Y2 à 0 et DUREE_Y2 à 0 .... et vice versa ... dans la deuxième requête, j'ai mis NB_Y1 à 0 et DUREE_Y1 à 0 ... donc forcement quand je sum ... j'ai bien mes dates avec les bonnes valeurs !!

Je voulais faire ça car les utilisateurs de mon application m'ont demandé de pouvoir saisir des paramètre commun aux deux requêtes et des 'nature d'activité' différente ...
pour afficher un graphique (grâce à JPGraph ... je suis devenu un pro ;-) ) .... ou pour un mois en axis j'ai deux barres (NB_Y1 et NB_Y2 ... ou la durée (choisis en paramètre) ) ... puis faire une courbe sur du Ration entre Y1 et Y2 ...

Image

C'est que c'est relou un utilisateur !!!
La vie est faite d'imprevu, et l'imprevu fait la vie
Gardez la peche !!

Eléphant du PHP | 193 Messages

24 août 2007, 17:53

Ah bah c'est que je proposais. Par contre le order by à la fin est inutile, le GROUP BY classe de cette façon tout seul a priori.

Ish
Eléphant du PHP | 200 Messages

24 août 2007, 17:59

Ah bah c'est que je proposais. Par contre le order by à la fin est inutile, le GROUP BY classe de cette façon tout seul a priori.
Oueh .... ça fait pas de mal !! :lol:
Donc je le laisse au cas où !! :wink:
La vie est faite d'imprevu, et l'imprevu fait la vie
Gardez la peche !!

Eléphant du PHP | 193 Messages

24 août 2007, 18:04

Disons que ça la requête marche mais est lourde, donc même sans benchmarker tout ça j'allègerais le code du "ORDER BY" et je remplacerais les "SUM (0)" par des "0" tout court.

Je sais pas si ça change quoi que ce soit mais... ça fait pas de mal ;)

Ish
Eléphant du PHP | 200 Messages

24 août 2007, 18:06

Disons que ça la requête marche mais est lourde, donc même sans benchmarker tout ça j'allègerais le code du "ORDER BY" et je remplacerais les "SUM (0)" par des "0" tout court.

Je sais pas si ça change quoi que ce soit mais... ça fait pas de mal ;)
Je vais tester ça !! ...
Mais ma requête initiale se fait en 0.109 s ... c'est pas mal pour une lourde requête comme ça
---------------
Je viens de tester et il n'y a pas de différence !!
La vie est faite d'imprevu, et l'imprevu fait la vie
Gardez la peche !!