2010-05-10 18 views
18

j'ai une procédure stockée comme suit:Modification d'un SUM retourné NULL à zéro

CREATE PROC [dbo].[Incidents] 
(@SiteName varchar(200)) 

AS 

SELECT 

( 
    SELECT SUM(i.Logged) 
    FROM tbl_Sites s 
    INNER JOIN tbl_Incidents i 
    ON s.Location = i.Location 
    WHERE s.Sites = @SiteName AND i.[month] = DATEADD(mm, DATEDIFF(mm, 0, GetDate()) -1,0) 
    GROUP BY s.Sites 
) AS LoggedIncidents 

'tbl_Sites contains a list of reported on sites. 
'tbl_Incidents containts a generated list of total incidents by site/date (monthly) 
'If a site doesnt have any incidents that month it wont be listed. 

Le problème que je vais avoir est qu'un site ne marche pas avoir d'incidents ce mois-ci et en tant que telle i obtenir une valeur NULL retournée pour ce site quand je lance ce sproc, mais j'ai besoin d'avoir un zéro/0 retourné pour être utilisé dans un graphique dans SSRS.

J'ai essayé l'utilisation coalesce et isnull en vain.

SELECT COALESCE(SUM(c.Logged,0)) 
    SELECT SUM(ISNULL(c.Logged,0)) 

Existe-t-il un moyen d'obtenir ce format correctement?

Cheers,

Lee

Répondre

35

mettre dehors:

SELECT COALESCE(

( 
    SELECT SUM(i.Logged) 
    FROM tbl_Sites s 
    INNER JOIN tbl_Incidents i 
    ON s.Location = i.Location 
    WHERE s.Sites = @SiteName AND i.[month] = DATEADD(mm, DATEDIFF(mm, 0, GetDate()) -1,0) 
    GROUP BY s.Sites 
), 0) AS LoggedIncidents 

Si vous retournez plusieurs lignes, changer INNER JOIN à LEFT JOIN

SELECT COALESCE(SUM(i.Logged),0) 
FROM tbl_Sites s 
LEFT JOIN tbl_Incidents i 
ON s.Location = i.Location 
WHERE s.Sites = @SiteName AND i.[month] = DATEADD(mm, DATEDIFF(mm, 0, GetDate()) -1,0) 
GROUP BY s.Sites 

Par manière, ne mettez aucune fonction ou exprimer ion à l'intérieur des fonctions agrégées si cela n'est pas justifié, par ex. ne pas mettre ISNULL, COALESCE intérieur de SUM, en utilisant la fonction/expression dans l'agrégation estropiés performance, la requête sera exécutée avec le balayage de table

+0

Je suis confus parmi beaucoup anwsers que j'ai trouvé pour la question que je faisais face, mais par la suite « COALESCE (SUM (i.Logged) , 0) "fait l'affaire, et d'une manière très élégante et simple. Merci!! – TheCuBeMan

18

Vous devez utiliser ISNULL comme ça -

ISNULL(SUM(c.Logged), 0)  

Ou , comme l'a dit Michael, vous pouvez utiliser une jointure extérieure gauche.

1

Vous pouvez envelopper le SELECT dans un autre SELECT comme ceci:

CREATE PROC [dbo].[Incidents] 
(@SiteName varchar(200)) 

AS 

SELECT COALESCE(TotalIncidents ,0) 
FROM (
    SELECT 
    ( 
    SELECT SUM(i.Logged) as TotalIncidents 
    FROM tbl_Sites s 
    INNER JOIN tbl_Incidents i 
    ON s.Location = i.Location 
    WHERE s.Sites = @SiteName AND i.[month] = DATEADD(mm, DATEDIFF(mm, 0, GetDate()) -1,0) 
    GROUP BY s.Sites 
) AS LoggedIncidents 
) 
2

Le plus simple, et la plus lisible, comme je l'ai trouvé d'y arriver est par:

CREATE PROC [dbo].[Incidents] 
(@SiteName varchar(200)) 

AS 

    SELECT SUM(COALESCE(i.Logged, 0)) AS LoggedIncidents 
    FROM tbl_Sites s 
    INNER JOIN tbl_Incidents i 
    ON s.Location = i.Location 
    WHERE s.Sites = @SiteName 
      AND i.[month] = DATEADD(mm, DATEDIFF(mm, 0, GetDate()) -1,0) 
    GROUP BY s.Sites 
+1

Si aucune ligne n'est trouvée dans tbl_Sites SUM n'est pas évalué et renvoie NULL. –

1

Je viens de croiser ce problème, la solution de Kirtan a bien fonctionné pour moi, mais la syntaxe était un peu éteinte. J'ai fait comme ceci:

ISNULL(SUM(c.Logged), 0) 

Le message m'a aidé à résoudre mon problème cependant merci à tous.

+0

mais ISNULL introuvable dans Oracle – Gank

6

J'ai rencontré ce problème dans Oracle. Oracle n'a pas de fonction ISNULL(). Cependant, nous pouvons utiliser la fonction NVL() pour obtenir le même résultat:

NVL(SUM(c.Logged), 0)