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

Nicolas___ 1039 Messages postés jeudi 2 novembre 2000Date d'inscription 24 avril 2013 Dernière intervention - 23 avril 2013 à 15:19 - Dernière réponse : Nicolas___ 1039 Messages postés jeudi 2 novembre 2000Date d'inscription 24 avril 2013 Dernière intervention
- 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___
Afficher la suite 

Votre réponse

4 réponses

Meilleure réponse
cs_Malkuth 278 Messages postés samedi 22 février 2003Date d'inscription 24 avril 2013 Dernière intervention - 24 avril 2013 à 12:41
3
Merci
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];

Merci cs_Malkuth 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 83 internautes ce mois-ci

Commenter la réponse de cs_Malkuth
yann_lo_san 1137 Messages postés lundi 17 novembre 2003Date d'inscription 23 janvier 2016 Dernière intervention - 23 avril 2013 à 20:58
0
Merci
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...
Commenter la réponse de yann_lo_san
Nicolas___ 1039 Messages postés jeudi 2 novembre 2000Date d'inscription 24 avril 2013 Dernière intervention - 24 avril 2013 à 08:03
0
Merci
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___
Commenter la réponse de Nicolas___
Nicolas___ 1039 Messages postés jeudi 2 novembre 2000Date d'inscription 24 avril 2013 Dernière intervention - 24 avril 2013 à 13:08
0
Merci
@ 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___
Commenter la réponse de Nicolas___

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.