Computed Column dans une requête [Résolu]

Signaler
Messages postés
992
Date d'inscription
jeudi 2 novembre 2000
Statut
Membre
Dernière intervention
24 avril 2013
-
Messages postés
992
Date d'inscription
jeudi 2 novembre 2000
Statut
Membre
Dernière intervention
24 avril 2013
-
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

Messages postés
268
Date d'inscription
samedi 22 février 2003
Statut
Membre
Dernière intervention
24 avril 2013
2
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];
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
20
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...
Messages postés
992
Date d'inscription
jeudi 2 novembre 2000
Statut
Membre
Dernière intervention
24 avril 2013
2
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___
Messages postés
992
Date d'inscription
jeudi 2 novembre 2000
Statut
Membre
Dernière intervention
24 avril 2013
2
@ 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___