Computed Column dans une requête

Résolu
Nicolas___ Messages postés 992 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 24 avril 2013 - 23 avril 2013 à 15:19
Nicolas___ Messages postés 992 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 24 avril 2013 - 24 avril 2013 à 13:08
Bonjour,

Je connais cette utilisation des "Computed Column" dans SQL_SERVER (2008).

Exemple :
DECLARE @tbl TABLE (A INT , B INT , C AS (A+B) ) 

INSERT INTO @tbl(A,B) SELECT 5,4 UNION ALL SELECT 10,54

SELECT * FROM @tbl



qui donne comme résultat ceci :

A |B |C
5 |4 |9
10 |54 |64

Mais est-il possible de réaliser ceci directement à partir d'un Query ?
Avec une utilisation comme ceci par exemple :

SELECT 
'a' = 5,
'b' = 4,
'c' = 'a'+'b'

(Je sais très bien que l'exemple si dessus ne marche pas ... enfin ne donne pas le résultat voulu en tout cas )


Les exemples sont bien évidement simpliste ;)

Merci,

bien à vous,

Nicolas___

4 réponses

cs_Malkuth Messages postés 268 Date d'inscription samedi 22 février 2003 Statut Membre Dernière intervention 24 avril 2013 4
24 avril 2013 à 12:41
2 réponse :

La premiére est à vérifier mais je pense que l'optimiseur de requette de SQL Serveur détecte la répétition de code et fais lui même les optimisations adéquates, tu dois pouvoir t'en assuré en analysant le plan d'execution de la requette.

La seconde serais de passé par une sous-requette ou une CTE :

DECLARE @AvgTimeMaint_SEC INT = 42;

SELECT
    [SRC].[RqtCode],
    [SRC].[Dte],
    [SRC].[CpyCode],
    [SRC].[Obj_Blabla],
    [SRC].[Obj_Blabla2],
    [SRC].[Obj_Blabla3],
    [SRC].[Obj_Blabla] + [SRC].[Obj_Blabla2] + [SRC].[Obj_Blabla3] AS [TotObjMaint]
FROM (
    SELECT
        RQT.RqtCode,
        RQT.Dte,
        CPY.CpyCode,
        'Obj_Blabla' = dbo.GetNbObj(CPY.CpyInCde,100) * @AvgTimeMaint_SEC,
'Obj_Blabla2' = dbo.GetNbObj(CPY.CpyInCde,200) * @AvgTimeMaint_SEC,
'Obj_Blabla3' = dbo.GetNbObj(CPY.CpyInCde,300) * @AvgTimeMaint_SEC
    FROM Request AS RQT
    INNER JOIN Company AS CPY
        ON RQT.OrigCpyInCde = CPY.CpyInCde
    WHERE
        ... -- pas important ici
) AS [SRC];


Qui peux s'écrire pour plus de clarté :


DECLARE @AvgTimeMaint_SEC INT = 42;

WITH [SRC] AS (
    SELECT
        RQT.RqtCode,
        RQT.Dte,
        CPY.CpyCode,
        'Obj_Blabla' = dbo.GetNbObj(CPY.CpyInCde,100) * @AvgTimeMaint_SEC,
'Obj_Blabla2' = dbo.GetNbObj(CPY.CpyInCde,200) * @AvgTimeMaint_SEC,
'Obj_Blabla3' = dbo.GetNbObj(CPY.CpyInCde,300) * @AvgTimeMaint_SEC
    FROM Request AS RQT
    INNER JOIN Company AS CPY
        ON RQT.OrigCpyInCde = CPY.CpyInCde
    WHERE
        ... -- pas important ici
)
SELECT
    [SRC].[RqtCode],
    [SRC].[Dte],
    [SRC].[CpyCode],
    [SRC].[Obj_Blabla],
    [SRC].[Obj_Blabla2],
    [SRC].[Obj_Blabla3],
    [SRC].[Obj_Blabla] + [SRC].[Obj_Blabla2] + [SRC].[Obj_Blabla3] AS [TotObjMaint]
FROM [SRC];
3
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
23 avril 2013 à 20:58
Salut,

ben si les champs du select proviennent d'une table, il suffit d'utiliser le nom des champs :

DECLARE @T table (a int, b int, c int null);
INSERT INTO @T(a,b) VALUES(5,10);
SELECT 
a,
b,
c = a+b
FROM @T


Pour des valeurs constantes, c'est pareil !

je ne vois dans quel cas cela ne marcherait pas ?

bye...
0
Nicolas___ Messages postés 992 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 24 avril 2013 1
24 avril 2013 à 08:03
Bonjour,

l'exemple était trop simpliste je m'explique donc plus en détail :

j'ai une requête créée comme ceci (ça reste de l'exemple mais cette fois-ci on est dans mon cas "d'étude" ):

DECLARE @AvgTimeMaint_SEC INT = 42

SELECT
RQT.RqtCode,
RQT.Dte,
CPY.CpyCode,
'Obj_Blabla' = dbo.GetNbObj(CPY.CpyInCde,100) * @AvgTimeMaint_SEC, -- 100 represente la clef primaire de l'objet 
'Obj_Blabla2' = dbo.GetNbObj(CPY.CpyInCde,200) * @AvgTimeMaint_SEC, -- 200 represente la clef primaire de l'objet 
'Obj_Blabla3' = dbo.GetNbObj(CPY.CpyInCde,300) * @AvgTimeMaint_SEC, -- 300 represente la clef primaire de l'objet 
'TotObjMaint' = 
dbo.GetNbObj(CPY.CpyInCde,100) * @AvgTimeMaint_SEC + 
dbo.GetNbObj(CPY.CpyInCde,200) * @AvgTimeMaint_SEC + 
dbo.GetNbObj(CPY.CpyInCde,300) * @AvgTimeMaint_SEC
FROM
Request RQT
INNER JOIN Company CPY ON RQT.OrigCpyInCde = CPY.CpyInCde
WHERE
... -- pas important ici


GetNbObj est une fonction scalar qui me retourne le nombre d'objet pour une société sur un objet donné (100,200,300)

Ce que je veux éviter, c'est cette ligne dans cette requête (répétition inutile de "code")
'TotObjMaint' = 
dbo.GetNbObj(CPY.CpyInCde,100) * @AvgTimeMaint_SEC + 
dbo.GetNbObj(CPY.CpyInCde,200) * @AvgTimeMaint_SEC + 
dbo.GetNbObj(CPY.CpyInCde,300) * @AvgTimeMaint_SEC


Vu que j'ai déjà récupéré ces valeurs via les colonnes Obj_Blabla,Obj_Blabla2,Obj_Blabla3.
Et je dois aussi bien récupérer la valeur de chaque obj que le total ... pour faire une analogie, dans excel, ma colonne
TotObjMaint serait une formule qui serait calculée à partir des autres colonnes.


J'aimerais donc pouvoir faire, à la manière d'une computed colum dans une table MAIS sans passer par une table temporaire,
'TotObjMaint' = Obj_Blabla + Obj_Blabla2 + Obj_Blabla3


J'espère avoir été plus clair ...

Bien à vous,

Nicolas___
0
Nicolas___ Messages postés 992 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 24 avril 2013 1
24 avril 2013 à 13:08
@ Malkuth :

Mais mais mais ... MAIS OUI :D
C'est tellement évident maintenant ! Le pire, c'est que je connais cette "astuce" !

Pour la première réponse, je vais regarder à ça mais je n'ai pas les autorisations au boulot

Réponse acceptée


@yann_lo_san : merci d'avoir pris le temps de regarder à ma question ;)

bien à vous,
Nicolas___
0
Rejoignez-nous