2010-03-02 15 views
3

J'ai donc 3 colonnes différentes (panier 1, 2 et 3). Parfois ces colonnes ont toutes les informations et parfois une ou deux d'entre elles sont nulles. J'ai une autre colonne dans laquelle je vais faire la moyenne de ces valeurs et enregistrer.Colonnes moyennes MS-SQL avec NULL

Existe-t-il un moyen élégant/facile d'obtenir la moyenne de ces trois colonnes même si l'une d'entre elles est nulle? Ou dois-je avoir un chèque spécial pour chacun étant nul?

données Exemple (~~ est nul)

- B1 - B2 - B3 - Avg 
------------------------------ 
- 10 - 20 - 30 - 20 
- 10 - ~~ - 30 - 20 
- ~~ - 20 - ~~ - 20 

Comment pourrais-je écrire le T-SQL pour mettre à jour ma table temp?

UPDATE @MyTable 
    SET Avg = ??? 

Réponse: Merci à Aaronaught pour la méthode je. Je vais mettre mon code ici juste au cas où quelqu'un d'autre aurait la même chose.

WITH AverageView AS 
(
    SELECT Results_Key AS xxx_Results_Key, 
      AVG(AverageValue) AS xxx_Results_Average 
    FROM @MyResults 
     UNPIVOT (AverageValue FOR B IN (Results_Basket_1_Price, Results_Basket_2_Price, Results_Basket_3_Price)) AS UnpivotTable 
    GROUP BY Results_Key 
) 
UPDATE @MyResults 
    SET Results_Baskets_Average_Price = xxx_Results_Average 
    FROM AverageView 
    WHERE Results_Key = xxx_Results_Key; 
+0

Quels SGBDR utilisez-vous? – Quassnoi

Répondre

4

En supposant que vous avez une sorte de colonne ID, la façon la plus efficace est sans doute d'utiliser UNPIVOT de sorte que vous pouvez utiliser l'opérateur AVG en rangée normale (qui ne tient pas compte NULL valeurs):

DECLARE @Tbl TABLE 
(
    ID int, 
    B1 int, 
    B2 int, 
    B3 int 
) 

INSERT @Tbl (ID, B1, B2, B3) VALUES (1, 10, 20, 30) 
INSERT @Tbl (ID, B1, B2, B3) VALUES (2, 10, NULL, 30) 
INSERT @Tbl (ID, B1, B2, B3) VALUES (3, 10, NULL, NULL) 

SELECT ID, AVG(Value) AS Average 
FROM @Tbl 
UNPIVOT (Value FOR B IN (B1, B2, B3)) AS u 
GROUP BY ID 

Si vous ne disposez pas de la colonne ID, vous pouvez générer un ID de remplacement en utilisant ROW_NUMBER:

;WITH CTE AS 
(
    SELECT 
     B1, B2, B3, 
     ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS ID 
    FROM @Tbl 
) 
SELECT ID, AVG(Value) 
FROM CTE 
UNPIVOT (Value FOR B IN (B1, B2, B3)) AS u 
GROUP BY ID 
+0

+1 mais notez que cela utilise une extension non standard. –

+0

Parfait, cela a fait exactement ce dont j'avais besoin – Miles

1
SELECT (
     SELECT AVG(b) 
     FROM (
       SELECT b1 AS b 
       UNION ALL 
       SELECT b2 
       UNION ALL 
       SELECT b3 
       ) q 
     ) 
FROM mytable 
0
SELECT (ISNULL(B1,0) + ISNULL(B2,0) + ISNULL(B3,0)) 
/(CASE WHEN B1 IS NULL THEN 0 ELSE 1 END 
+CASE WHEN B2 IS NULL THEN 0 ELSE 1 END 
+CASE WHEN B3 IS NULL THEN 0 ELSE 1 END) 

et de mettre la logique là pour exclure les cas où tous les trois sont nuls si vous avez besoin.

Questions connexes