Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server
MS SQL-Server Forum Microsoft SQL-Server. Avant de poster -> FAQ SQL-Server, Tutoriels SQL-Server
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 27/12/2010, 16h34   #1
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Par défaut [SQL2005] Raccourci pour expressions similaires

Est-il possible d'utiliser directement un résultat que l'on vient de calculer pour une autre expression ?
Voici un exemple plus explicite de ma question :

Code :
1
2
3
4
SELECT  C1 + C2 AS [addition_1],
	[addition1] + C3 AS [addition_2]
 
FROM	my_table


au lieu de

Code :
1
2
3
4
SELECT  C1 + C2 AS [addition_1],
	C1 + C2 + C3 AS [addition_2]
 
FROM	my_table



Le but serait d'utiliser une fonction raccourci qui permettrait d'éviter de réecrire l'expression entière.

Merci pour votre aide.
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2010, 16h49   #2
Modérateur
 
Avatar de Jinroh77
 
Homme Alexandre Chemla
Consultant en Business Intelligence
Inscription : février 2006
Messages : 1 770
Détails du profil
Informations personnelles :
Nom : Homme Alexandre Chemla
Âge : 28
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : Consultant en Business Intelligence

Informations forums :
Inscription : février 2006
Messages : 1 770
Points : 1 833
Points : 1 833
Directement dans le select, non? Mais vous pouvez utiliser une CTE (à partir de SQL 2005) pour pré-calculer votre premier résultat.
Code :
1
2
3
4
5
6
7
8
WITH t (somme) AS (
	SELECT 
	 1 + 1 AS somme
 )
SELECT 
	somme
	,somme + 1
FROM t
Jinroh77 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2010, 16h52   #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

"directement", non.

par contre vous pouvez faire ceci :
Code sql :
1
2
3
4
5
6
7
 
SELECT addition1, addition1 + C3 AS addition2
FROM
(
  SELECT C1 + C2  AS addition1, C3
  FROM MaTable
) AS tmp

Mais je ne vois pas l'intérêt
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2010, 17h35   #4
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Bonsoir,

n'y a t'il aucun moyen de faire ceci sans modifier la clause FROM ?
Car dans ma query initiale, j'ai déjà plusieurs join qui s'y affère. Dès lors, je commence à m'emmeler.

L'intêret est d'allléger/améliorer la visibilité de ma query.
Je vous ai donné ici un exemple simple, mais ma query est bien plus complexe.
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2010, 18h02   #5
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
Puisque vous semblez être en 2005, et si votre but est d'améliorer la lisibilité de votre requete, alors la solution de Jinroh77 est surement ce qu'il vous faut !

En gros dans votre cas cela revient a définir avant la requete elle même des résultats intermédiaires. Vous vous y retrouverez donc facilement dans la requete par la suite.

En fonction de vos besoins, une vue pourrait aussi être une solution adaptée


Enfin, mais cela n'engage que moi, dans votre question initiale, je trouve que votre deuxième requete, bien indentée, est bien plus lisible que la première !
En effet, on voit très vite que la deuxième ligne du SELECT reprend la première...

Effectivement, si votre requete est vraiment très compliquée, avec de nombreux calculs imbriqués, alors passez soit par une CTE, soit par une vue(qui en plus pourra peut être être indexée par la suite pour améliorer les performances de votre requete)
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2010, 12h14   #6
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Merci pour vos suggestions.
Dès lors, pourrai-je vous demander comment vous simplifieriez ce code ci-dessous svp ?!

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
SELECT
 
CASE WHEN condition1 THEN 0
     ELSE
	     CASE WHEN condition2 THEN 0
                  WHEN condition3 THEN 1					
                  WHEN condition4 THEN 1
		  ELSE 0
	     END
END AS [C1],
 
 
CASE WHEN condition1 THEN 0	
     ELSE
	     CASE WHEN condition 5 THEN 0
		  ELSE 
	              CASE WHEN condition2 THEN 0
                           WHEN condition3 THEN 1
                           WHEN condition4 THEN 1
                           ELSE 0
		      END
	     END
END AS [C2],
 
et ainsi de suite..
 
FROM my_table
Merci d'avance.
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2010, 12h32   #7
Modérateur
 
Avatar de Jinroh77
 
Homme Alexandre Chemla
Consultant en Business Intelligence
Inscription : février 2006
Messages : 1 770
Détails du profil
Informations personnelles :
Nom : Homme Alexandre Chemla
Âge : 28
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : Consultant en Business Intelligence

Informations forums :
Inscription : février 2006
Messages : 1 770
Points : 1 833
Points : 1 833
La valeur de C2 utilise dans son CASE WHEN la valeur de C1 ?
Jinroh77 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2010, 12h42   #8
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Citation:
Envoyé par Jinroh77 Voir le message
La valeur de C2 utilise dans son CASE WHEN la valeur de C1 ?
Oui !
Et la valeur de C3 dépend de la valeur de C2, et ainsi de suite.
Chacune de mes colonnes dépendent des colonnes précédentes, auxquelles j'ajoute des conditions supplémentaires.
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2010, 13h53   #9
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
Tu peux aussi utiliser les UDF...
La ta requete pourra vraiment être plus lisible surtout si tu met de la logique métier, ca peut être aussi une bonne solution

Mais tu a besoin des résultats intermédiaires au final, ou c'est juste pour vérifier que ta requete fonctionne bien, et donc avoir les différentes étapes pour debugguer ?
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2010, 14h13   #10
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Citation:
Envoyé par aieeeuuuuu Voir le message
Mais tu a besoin des résultats intermédiaires au final, ou c'est juste pour vérifier que ta requete fonctionne bien, et donc avoir les différentes étapes pour debugguer ?
J'ai besoin de toutes les étapes dans mon résultat.
Je suis novice, mais je souhaite en apprendre tous les jours.
UDF ? je vais checker ca, mais pour info..

je DOIS avoir tout mon code dans une seule et même reqûete.

Merci d'avance
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2010, 14h44   #11
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 apnw7931 Voir le message
je DOIS avoir tout mon code dans une seule et même reqûete.
C'est a dire ?
tu veux récupérer tes résultats en une seule requete ?
ou tu veux toute la logique de calcul dans une seule requete SQL ? dans ce cas pourquoi ?
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2010, 15h03   #12
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Citation:
Envoyé par aieeeuuuuu Voir le message
C'est a dire ?
tu veux récupérer tes résultats en une seule requete ?
ou tu veux toute la logique de calcul dans une seule requete SQL ? dans ce cas pourquoi ?
Je souhaite tout avoir dans une seule reqûete, sans créer de procédures ou de fonctions qui viendraient écrire dans la base de données. En effet, je n'ai qu'un accès 'Read Only' à la Data Warehouse. J'espere que je me suis mieux fait comprendre.

Sinon, pour en revenir à mon exemple, je peux l'expliquer d'une autre manière.
Je souhaiterai savoir comment faire ceci :

Code :
1
2
3
(CASE xxx WHEN xxx THEN xxx ELSE xxx END) AS [C1],
(CASE [C1] WHEN xxx ...) AS [C2],
etc..
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2010, 15h20   #13
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
les fonctions en question n'ecriraient pas dans la base de données, et ne lirait pas non plus d'ailleurs. Elles pourraient simplement prendre en parametre les données que tu traitera dans ton SELECT, et effectuer le calcul dessus.(tu pourrait juste encapsuler tes case dans ces fonctions)

Par contre effectivement il te faudra les privilèges de création pour les fonctions... puis les privilèges pour les exécuter...
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2010, 15h23   #14
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Vois-tu alors une solution à mon problème ?!
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2010, 15h39   #15
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 apnw7931 Voir le message
je n'ai qu'un accès 'Read Only' à la Data Warehouse

Vois-tu alors une solution à mon problème ?!

J'en vois plusieurs :
1/ demander au DBA de faire son travail.
2/ demander au DBA de te donner les privilèges nécessaires pour que tu puisse faire son travail
3/ revenir a la solution des CTE, voire ta solution initiale, car après tout il ne s'agit ici que d'un problème de lisibilité!
comme je le disais plus haut, une requete bien indentée peu rester lisible même avec plusieurs imbrications de CASE...
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2010, 15h52   #16
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
je vais donc devoir opter pour l'option numéro 3 : CTE.

Par contre, pourrais-je abuser de vos aides pour me réécrire ces lignes de code, mais avec l'utilisation d'un WITH ?!
Etant novice, je vais prendre beaucoup de temps pour le faire (mais j'essaye quand même dès la fin de mon message).
Je vous en serais reconnaissant.

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
ELECT
 
CASE WHEN condition1 THEN 0
     ELSE
	     CASE WHEN condition2 THEN 0
                  WHEN condition3 THEN 1					
                  WHEN condition4 THEN 1
		  ELSE 0
	     END
END AS [C1],
 
 
CASE WHEN condition1 THEN 0	
     ELSE
	     CASE WHEN condition 5 THEN 0
		  ELSE 
	              CASE WHEN condition2 THEN 0
                           WHEN condition3 THEN 1
                           WHEN condition4 THEN 1
                           ELSE 0
		      END
	     END
END AS [C2],
 
et ainsi de suite..
 
FROM my_table
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2010, 16h30   #17
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 condition1 correspond a col1 = UnGrosCalcul(col2, col3)

Alors, tu dois fauire quelque chose du genre

Code sql :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
WITH intermediare(UnGrosResultat) AS (
    SELECT ID, UnGrosCalcul(col2,col3)
    FROM MaTable
)
SELECT
    CASE WHEN Col1 = intermediaire.UnGrosResultat THEN 0
        ELSE CASE... END
    END,
    CASE WHEN Col1 = intermediaire.UnGrosResultat THEN 0 
        ELSE CASE ... END
    END,
...
FROM MaTable
INNER JOIN intermediaire ON MaTable.ID = intermediaire.ID

Tu pourrai aussi ajouter les autres calculs de la même façon (condition2, condition3, et condition4), mais tu risque de faire pas mal de calculs inutiles (si condition1 est vrai tout le temps, les calculs pour condition2, condition3 et condition4 ne seront jamais effectués, et condition5 ne sera même jamais évaluée), donc tu risque de perdre pas mal en performance.

Dans ce cas, il faudra faire une deuxième CTE, avec une jointure sur la première et une clause WHERE du type
WHERE NOT col1 = intermediare.UnGrosResultat

et ainsi de suite
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2010, 16h40   #18
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Merci beaucoup. Je vais essayer de chipoter et d'arriver à mon résultat avec ceci.

Sinon, parrallèlement, je n'arrive pas à joindre correctement ceci.
J'aimerai avoir la somme de chacun des WITH.

Code :
1
2
3
4
5
6
7
8
WITH
a (TEST1) AS (SELECT column1 FROM my_table),
b (TEST2) AS (SELECT column2 FROM my_table)
 
SELECT	SUM(TEST1),
        SUM(TEST2)
 
FROM	??
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2010, 16h54   #19
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
comme ceci :

Code sql :
1
2
3
4
5
6
7
8
 
WITH
a (TEST1) AS (SELECT column1 FROM my_table),
b (TEST2) AS (SELECT column2 FROM my_table)
 
SELECT SUM(TEST1),
     (SELECT SUM(TEST2) FROM b)
FROM	a
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 10h08.


 
 
 
 
Partenaires

Hébergement Web