Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 21/02/2011, 16h12   #1
Candidat au titre de Membre du Club
 
Inscription : mai 2006
Messages : 51
Détails du profil
Informations forums :
Inscription : mai 2006
Messages : 51
Points : 13
Points : 13
Par défaut Fusion de 2 select : comment faire ?

Bonjour,

J'ai besoin de retourner le résultat provenant de 2 select différents en ne faisant en réalité qu'1 seul select. Je m'explique :

Voici mon code :
Code :
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
 
Declare @annee AS int
 
SET @annee = 2010
 
SELECT
  C.NOM_CLIENT,
  OCT   = SUM(CASE WHEN MONTH(SCD.DATE)=10 AND YEAR(SCD.DATE)=@ANNEE   AND SCD.DATE >= getdate() THEN SCD.MONTANT_EURO ELSE 0 END),
  NOV   = SUM(CASE WHEN MONTH(SCD.DATE)=11 AND YEAR(SCD.DATE)=@ANNEE   AND SCD.DATE >= getdate() THEN SCD.MONTANT_EURO ELSE 0 END),
  DEC   = SUM(CASE WHEN MONTH(SCD.DATE)=12 AND YEAR(SCD.DATE)=@ANNEE   AND SCD.DATE >= getdate() THEN SCD.MONTANT_EURO ELSE 0 END),
  JANV  = SUM(CASE WHEN MONTH(SCD.DATE)=1  AND YEAR(SCD.DATE)=@ANNEE+1 AND SCD.DATE >= getdate() THEN SCD.MONTANT_EURO ELSE 0 END),
  FEV   = SUM(CASE WHEN MONTH(SCD.DATE)=2  AND YEAR(SCD.DATE)=@ANNEE+1 AND SCD.DATE >= getdate() THEN SCD.MONTANT_EURO ELSE 0 END),
  MARS  = SUM(CASE WHEN MONTH(SCD.DATE)=3  AND YEAR(SCD.DATE)=@ANNEE+1 AND SCD.DATE >= getdate() THEN SCD.MONTANT_EURO ELSE 0 END),
  AVRIL = SUM(CASE WHEN MONTH(SCD.DATE)=4  AND YEAR(SCD.DATE)=@ANNEE+1 AND SCD.DATE >= getdate() THEN SCD.MONTANT_EURO ELSE 0 END),
  MAI   = SUM(CASE WHEN MONTH(SCD.DATE)=5  AND YEAR(SCD.DATE)=@ANNEE+1 AND SCD.DATE >= getdate() THEN SCD.MONTANT_EURO ELSE 0 END),
  JUIN  = SUM(CASE WHEN MONTH(SCD.DATE)=6  AND YEAR(SCD.DATE)=@ANNEE+1 AND SCD.DATE >= getdate() THEN SCD.MONTANT_EURO ELSE 0 END),
  JUIL  = SUM(CASE WHEN MONTH(SCD.DATE)=7  AND YEAR(SCD.DATE)=@ANNEE+1 AND SCD.DATE >= getdate() THEN SCD.MONTANT_EURO ELSE 0 END),
  AOUT  = SUM(CASE WHEN MONTH(SCD.DATE)=8  AND YEAR(SCD.DATE)=@ANNEE+1 AND SCD.DATE >= getdate() THEN SCD.MONTANT_EURO ELSE 0 END),
  SEPT  = SUM(CASE WHEN MONTH(SCD.DATE)=9  AND YEAR(SCD.DATE)=@ANNEE+1 AND SCD.DATE >= getdate() THEN SCD.MONTANT_EURO ELSE 0 END),
  TOTAL = SUM(CASE WHEN (MONTH(SCD.DATE)>=10 AND (YEAR(SCD.DATE)=@ANNEE) OR (MONTH(SCD.DATE) <= 9 AND YEAR(SCD.DATE)=@ANNEE + 1)) AND SCD.DATE >= getdate() THEN SCD.MONTANT_EURO ELSE 0 END)
FROM SCD, CDE, CLIENT C, AFFAIRE A    
WHERE SCD.N_CDE_CLI = CDE.N_CDE_CLI
AND   CDE.N_affaire = A.N_affaire
AND   A.N_CLIENT    = C.N_CLIENT
GROUP BY C.NOM_CLIENT
 
UNION ALL
 
SELECT
  C.NOM_CLIENT,
  OCT =   SUM(CASE WHEN MONTH(DATE_FACTURE)=10 AND YEAR(DATE_FACTURE)=@ANNEE   AND DATE_FACTURE < getdate() THEN (CASE WHEN F.AVOIR='OUI' THEN -HT_EURO ELSE HT_EURO END) ELSE 0 END),
  NOV =   SUM(CASE WHEN MONTH(DATE_FACTURE)=11 AND YEAR(DATE_FACTURE)=@ANNEE   AND DATE_FACTURE < getdate() THEN (CASE WHEN F.AVOIR='OUI' THEN -HT_EURO ELSE HT_EURO END) ELSE 0 END),
  DEC =   SUM(CASE WHEN MONTH(DATE_FACTURE)=12 AND YEAR(DATE_FACTURE)=@ANNEE   AND DATE_FACTURE < getdate() THEN (CASE WHEN F.AVOIR='OUI' THEN -HT_EURO ELSE HT_EURO END) ELSE 0 END),
  JANV =  SUM(CASE WHEN MONTH(DATE_FACTURE)=1  AND YEAR(DATE_FACTURE)=@ANNEE+1 AND DATE_FACTURE < getdate() THEN (CASE WHEN F.AVOIR='OUI' THEN -HT_EURO ELSE HT_EURO END) ELSE 0 END),
  FEV =   SUM(CASE WHEN MONTH(DATE_FACTURE)=2  AND YEAR(DATE_FACTURE)=@ANNEE+1 AND DATE_FACTURE < getdate() THEN (CASE WHEN F.AVOIR='OUI' THEN -HT_EURO ELSE HT_EURO END) ELSE 0 END),
  MARS =  SUM(CASE WHEN MONTH(DATE_FACTURE)=3  AND YEAR(DATE_FACTURE)=@ANNEE+1 AND DATE_FACTURE < getdate() THEN (CASE WHEN F.AVOIR='OUI' THEN -HT_EURO ELSE HT_EURO END) ELSE 0 END),
  AVRIL = SUM(CASE WHEN MONTH(DATE_FACTURE)=4  AND YEAR(DATE_FACTURE)=@ANNEE+1 AND DATE_FACTURE < getdate() THEN (CASE WHEN F.AVOIR='OUI' THEN -HT_EURO ELSE HT_EURO END) ELSE 0 END),
  MAI =   SUM(CASE WHEN MONTH(DATE_FACTURE)=5  AND YEAR(DATE_FACTURE)=@ANNEE+1 AND DATE_FACTURE < getdate() THEN (CASE WHEN F.AVOIR='OUI' THEN -HT_EURO ELSE HT_EURO END) ELSE 0 END),
  JUIN =  SUM(CASE WHEN MONTH(DATE_FACTURE)=6  AND YEAR(DATE_FACTURE)=@ANNEE+1 AND DATE_FACTURE < getdate() THEN (CASE WHEN F.AVOIR='OUI' THEN -HT_EURO ELSE HT_EURO END) ELSE 0 END),
  JUIL =  SUM(CASE WHEN MONTH(DATE_FACTURE)=7  AND YEAR(DATE_FACTURE)=@ANNEE+1 AND DATE_FACTURE < getdate() THEN (CASE WHEN F.AVOIR='OUI' THEN -HT_EURO ELSE HT_EURO END) ELSE 0 END),
  AOUT =  SUM(CASE WHEN MONTH(DATE_FACTURE)=8  AND YEAR(DATE_FACTURE)=@ANNEE+1 AND DATE_FACTURE < getdate() THEN (CASE WHEN F.AVOIR='OUI' THEN -HT_EURO ELSE HT_EURO END) ELSE 0 END),
  SEPT =  SUM(CASE WHEN MONTH(DATE_FACTURE)=9  AND YEAR(DATE_FACTURE)=@ANNEE+1 AND DATE_FACTURE < getdate() THEN (CASE WHEN F.AVOIR='OUI' THEN -HT_EURO ELSE HT_EURO END) ELSE 0 END),
  TOTAL = SUM(CASE WHEN (MONTH(DATE_FACTURE)>=10 AND (YEAR(DATE_FACTURE)=@ANNEE) OR (MONTH(DATE_FACTURE) <= 9 AND YEAR(DATE_FACTURE)=@ANNEE + 1)) AND DATE_FACTURE < getdate() THEN (CASE WHEN F.AVOIR='OUI' THEN -HT_EURO ELSE HT_EURO END) ELSE 0 END)
FROM FACTURE F, CLIENT C
WHERE F.N_CLIENT = C.N_CLIENT
GROUP BY C.NOM_CLIENT
ORDER BY C.NOM_CLIENT
Comme clients j'ai : TOTO, TITI et TATA

Le code précédent me retourne le résultat suivant :
Code :
1
2
3
4
5
6
7
 
TATA 	0.00	0.00	0.00	30.50	0.00	0.00	0.00	0.00	0.00	0.00	0.00	0.00	30.50
TATA 	0.00	0.00	0.00	0.00	488.00	0.00	0.00	0.00	0.00	0.00	0.00	0.00	488.00
TITI	0.00	0.00	0.00	286.26	0.00	0.00	0.00	0.00	0.00	0.00	0.00	0.00	286.26
TITI	0.00	0.00	0.00	0.00	0.00	0.00	0.00	0.00	3749.00	0.00	0.00	0.00	3749.00
TOTO	85.40	393.55	0.00	2928.90	0.00	0.00	0.00	0.00	0.00	0.00	0.00	0.00	3407.85
TOTO	0.00	0.00	0.00	0.00	0.00	24.40	18.30	76.25	0.00	45.75	36.60	24.40	225.70
Je souhaite faire une seule requête SELECT pour obtenir le résultat suivant :
Code :
1
2
3
4
 
TATA 	0.00	0.00	0.00	30.50	488.00	0.00	0.00	0.00	0.00	0.00	0.00	0.00	518.50
TITI	0.00	0.00	0.00	286.26	0.00	0.00	0.00	0.00	3749.00	0.00	0.00	0.00	4035.26
TOTO	85.40	393.55	0.00	2928.90	0.00	24.40	18.30	76.25	0.00	45.75	36.60	24.40	3633.55
En fait au lieu d'avoir 2 lignes par clients, j'ai ai 1 seule avec le cumul des valeurs de chaque ligne.

Que pouvez-vous me proposer pour répondre à mon besoin ?

Merci d'avance à tous.

Alf
bong03 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/02/2011, 16h46   #2
Expert Confirmé
 
Avatar de 7gyY9w1ZY6ySRgPeaefZ
 
Homme
dba
Inscription : juillet 2007
Messages : 2 520
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Canada

Informations professionnelles :
Activité : dba

Informations forums :
Inscription : juillet 2007
Messages : 2 520
Points : 3 967
Points : 3 967
quelque chose dans ce goût là :
Code :
1
2
3
4
5
6
SELECT CLI.Nom_client, sum ( coalesce (DEV.Mtt_devis , 0) ) + sum ( coalesce (FAC.Mtt_facture , 0) ) MTT_total
FROM Clients CLI
LEFT OUTER JOIN devis DEV
	ON DEV.id_client = CLI.id_client
LEFT OUTER JOIN facture FAC
	ON FAC.id_client = CLI.id_client
à vérifier : les cas où il n'y a pas de devis ou de facture pour un client donné.

[edit]Entre temps, la requête du demandeur s'est transformée radicalement.
__________________
les règles du forum - mode d'emploi du forum
Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs.
(Rappel : "ça ne marche pas" n'est pas un message d'erreur)
JE NE RÉPONDS PAS aux questions techniques par message privé.
Écrire en français sur un forum est une marque minimale de respect.
7gyY9w1ZY6ySRgPeaefZ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/02/2011, 16h48   #3
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Bonjour

Vous pouvez utiliser UNION ALL pour cela :

Code sql :
1
2
3
4
5
6
7
8
9
10
11
 
SELECT C.ID_Client, Nom_Client, COALESCE(SUM(Montant), 0)
FROM CLIENT C
LEFT OUTER JOIN (
    SELECT ID_Client, MTT_Devis AS Montant
    FROM DEVIS
    UNION ALL
    SELECT ID_Client, MTT_Facture AS Montant
    FROM FACTURE
) T ON C.ID_Client = T.ID_Client
GROUP BY C.IDClient, Nom_Client
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/02/2011, 16h55   #4
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Citation:
Envoyé par 7gyY9w1ZY6ySRgPeaefZ Voir le message
quelque chose dans ce goût là :
Code :
1
2
3
4
5
6
SELECT CLI.Nom_client, sum ( coalesce (DEV.Mtt_devis , 0) ) + sum ( coalesce (FAC.Mtt_facture , 0) ) MTT_total
FROM Clients CLI
LEFT OUTER JOIN devis DEV
	ON DEV.id_client = CLI.id_client
LEFT OUTER JOIN facture FAC
	ON FAC.id_client = CLI.id_client
à vérifier : les cas où il n'y a pas de devis ou de facture pour un client donné.
Hmmm, à vérifier aussi le cas ou un client a deux factures ET deux devis, chacun sera comptabilisé en double
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/02/2011, 17h03   #5
Expert Confirmé
 
Avatar de 7gyY9w1ZY6ySRgPeaefZ
 
Homme
dba
Inscription : juillet 2007
Messages : 2 520
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Canada

Informations professionnelles :
Activité : dba

Informations forums :
Inscription : juillet 2007
Messages : 2 520
Points : 3 967
Points : 3 967
Citation:
Envoyé par aieeeuuuuu Voir le message
Hmmm, à vérifier aussi le cas ou un client a deux factures ET deux devis, chacun sera comptabilisé en double
effectivement, c'est totalement cochon mon truc !
Ta solution est plus propre.
__________________
les règles du forum - mode d'emploi du forum
Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs.
(Rappel : "ça ne marche pas" n'est pas un message d'erreur)
JE NE RÉPONDS PAS aux questions techniques par message privé.
Écrire en français sur un forum est une marque minimale de respect.
7gyY9w1ZY6ySRgPeaefZ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/02/2011, 17h51   #6
Candidat au titre de Membre du Club
 
Inscription : mai 2006
Messages : 51
Détails du profil
Informations forums :
Inscription : mai 2006
Messages : 51
Points : 13
Points : 13
Bonsoir,

En effet mon premier post était carrément différent, mais ç'était à cause de la déconnexion du site : je mets trop de temps pour expliquer. La prochaine fois je ferais mon texte dans un éditeur et je ferai un copier/coller sur le site.

Alors j'ai trouvé une solution (radicalement differente), mais c'est trop long : 1minute 20 secondes de traitement alors que pour la version ci-dessus c'était 2 secondes.

Aussi, si vous avez d'autres suggestions par rapport à la requête du 1er post, je suis preneur.


Alf
bong03 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/02/2011, 18h12   #7
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Si la solution que vous avez postée met 5 secondes et que cela vous convient , vous pouvez appliquer directement la solution que je vous ai proposée,


Sinon, vous pouvez aussi utiliser le résultat de votre requête complète comme une pseudo table, et grouper de nouveau (pour faire la somme des sommes). Vous pourriez alors calculer votre TOTAL à ce moment là, pour éviter la dernière ligne de cases imbriqués... !

ça c'est pour les solutions rapides à mettre en oeuvre à partir de la requête que vous avez déjà écrite, mais qui pourrait être je pense optimisée.
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 12h59.


 
 
 
 
Partenaires

Hébergement Web