web-dev-qa-db-fra.com

Comment faire un SUM () dans une instruction case dans un serveur SQL

Je souhaite ajouter des calculs dans mon instruction case pour créer dynamiquement le contenu d'une nouvelle colonne, mais le message d'erreur suivant s'affiche: 

La colonne 'Test1.qrank' n'est pas valide dans la liste de sélection car elle ne figure ni dans une fonction d'agrégat ni dans la clause GROUP BY.

C'est le code sur lequel je travaille

case 
    when test1.TotalType = 'Average' then Test2.avgscore
    when test1.TotalType = 'PercentOfTot' then (cnt/SUM(test1.qrank))
    else cnt
end as displayscore

J'ai essayé de me regrouper mais cela n'a pas fonctionné.

Des allusions?

10
Athos

L'erreur que vous avez publiée peut survenir lorsque vous utilisez une clause dans l'instruction GROUP BY sans l'inclure dans la sélection.

Exemple

Celui-ci fonctionne!

     SELECT t.device,
            SUM(case when transits.direction = 1 then 1 else 0 end) ,
            SUM(case when transits.direction = 0 then 1 else 0 end) from t1 t 
            where t.device in ('A','B') group by t.device

Celui-ci non (t.device omis de la sélection)

     SELECT 
            SUM(case when transits.direction = 1 then 1 else 0 end) ,
            SUM(case when transits.direction = 0 then 1 else 0 end) from t1 t 
            where t.device in ('A','B') group by t.device

Cela produira votre erreur en vous plaignant que je regroupe quelque chose qui n'est pas inclus dans la sélection

S'il vous plaît, fournissez toute la requête pour obtenir plus de support.

21
Guglielmo Moretti

Vous pouvez utiliser une expression de table commune pour créer d’abord le SUM, le joindre à la table, puis utiliser le WHEN pour obtenir la valeur du CTE ou de la table originale selon les besoins.

WITH PercentageOfTotal (Id, Percentage) 
AS 
(
    SELECT Id, (cnt / SUM(AreaId)) FROM dbo.MyTable GROUP BY Id
)
SELECT 
    CASE
        WHEN o.TotalType = 'Average' THEN r.avgscore
        WHEN o.TotalType = 'PercentOfTot' THEN pt.Percentage
        ELSE o.cnt
    END AS [displayscore]
FROM PercentageOfTotal pt
    JOIN dbo.MyTable t ON pt.Id = t.Id
1
jacksonakj

Si vous utilisez SQL Server 2005 ou une version ultérieure, vous pouvez utiliser la fonction de fenêtrage SUM() OVER ().

case 
when test1.TotalType = 'Average' then Test2.avgscore
when test1.TotalType = 'PercentOfTot' then (cnt/SUM(test1.qrank) over ())
else cnt
end as displayscore

Mais ce sera mieux si vous affichez votre requête complète pour obtenir le contexte de ce dont vous avez réellement besoin.

0
RichardTheKiwi