使用视图的存储过程中的透视表管理空值

时间:2013-05-29 11:02:56

标签: sql-server stored-procedures

此存储过程结果存储总计基于查询,如果总共没有任何记录 然后在结果中想要0,如何管理空值。

CREATE PROCEDURE dbo.Procedure_Summary
    @UserID INT ,
    @Year INT    
AS
BEGIN

/* Procedure body */   

SELECT  UserID, 
        UserName ,
        [Marks1] as 'English',
        [Marks2] as 'Maths',
        [Marks3] as 'Science'
FROM 
    ( 
        SELECT l.UserID, 
                e.UserName , 
                s.SubjectName, 
                TotalMarks AS Total
        FROM ViewLeave l
            INNER JOIN  SubjectType  s  ON s.SubjectID = l.SubjectID  
            INNER JOIN UserInfo e ON e.UserID = l.UserID
        WHERE (( l.Result = 'Pass') 
                AND ( e.UserID = @UserID)
                AND l.[year]=@Year)
        GROUP BY s.SubjectName,l.UserID, e.UserName ,TotalDays
    )ps
    pivot
    (
        SUM(Total)
        FOR SubjectName IN ([Marks1],[Marks2],[Marks3])
    ) AS pvt           

END
  

当前结果和预期结果为 -

Accoding to current stored procedure result are as ,

UserID          UserName    English     Maths       Science 
105                 ABC     25      0       36
106                 XYZ     26      88      88

But i want if all three subject marks are 0 means total are zero and then show 
as , also show non zero record 


UserID          UserName    English     Maths       Science 
109                  QWE          0     0       0

3 个答案:

答案 0 :(得分:1)

试试这个 -

CREATE PROCEDURE dbo.Procedure_Summary

    @UserID INT ,
    @Year INT    

AS BEGIN

    SELECT  
          UserID
        , UserName 
        , [English] = [Marks1]
        , [Maths] = [Marks2]
        , [Science] = [Marks3]
    FROM 
    ( 
        SELECT 
              l.UserID
            , e.UserName 
            , s.SubjectName
            , Total = ISNULL(TotalMarks, 0) 
        FROM dbo.ViewLeave l
        LEFT JOIN dbo.SubjectType s ON s.SubjectID = l.SubjectID  
        LEFT JOIN dbo.UserInfo e ON e.UserID = l.UserID
        WHERE l.Result = 'Pass' 
            AND e.UserID = @UserID
            AND l.[year] = @Year
        GROUP BY 
              s.SubjectName
            , l.UserID
            , e.UserName 
            , TotalDays
    ) ps
    PIVOT
    (
        SUM(Total)
        FOR SubjectName In ([Marks1],[Marks2],[Marks3])
    ) pvt           

END

答案 1 :(得分:1)

很难完全回答这个问题,因为表格的细节并不是很好。

您可以尝试使用您传入的用户运行内部查询,以查看是否返回了任何数据:

SELECT l.UserID, 
   e.UserName , 
   s.SubjectName, 
   TotalMarks AS Total
FROM ViewLeave l
INNER JOIN  SubjectType  s  ON s.SubjectID = l.SubjectID  
INNER JOIN UserInfo e ON e.UserID = l.UserID
WHERE (( l.Result = 'Pass') 
   AND ( e.UserID = @UserID)
   AND l.[year]=@Year)
GROUP BY s.SubjectName,l.UserID, e.UserName ,TotalDays  -- I am not sure why you have this group by

我猜这部分问题就是你加入的方式。您正在使用内部联接,这将要求每个表中都存在行,但是UserInfo表正在筛选用户。所以我建议进行以下更改。

将您的JOIN更改为LEFT JOIN并使第一个表连接成UserInfo表,因此代码将为:

CREATE PROCEDURE dbo.Procedure_Summary
    @UserID INT ,
    @Year INT    
AS
BEGIN

/* Procedure body */   

SELECT  UserID, 
        UserName ,
        [Marks1] as 'English',
        [Marks2] as 'Maths',
        [Marks3] as 'Science'
FROM 
    ( 
        SELECT l.UserID, 
                e.UserName , 
                s.SubjectName, 
                TotalMarks AS Total
        FROM UserInfo e
        LEFT JOIN ViewLeave l 
          ON e.UserID = l.UserID
          AND l.Result = 'Pass'
          AND l.[year]=@Year
        LEFT JOIN  SubjectType  s  
          ON s.SubjectID = l.SubjectID  
        WHERE e.UserID = @UserID
    )ps
    pivot
    (
        SUM(Total)
        FOR SubjectName IN ([Marks1],[Marks2],[Marks3])
    ) AS pvt           

END

答案 2 :(得分:0)

        CREATE PROCEDURE dbo.Procedure_Summary @UserID INT , @Year INT    AS BEGIN

          /* Procedure body */   
            SELECT  UserID, UserName ,  [Marks1] as 'English',
                [Marks2] as 'Maths',
                [Marks3] as 'Science'  FROM   
    ( SELECT l.UserID,  e.UserName ,   s.SubjectName,  
     case when l.Result = 'Pass' 
     then l.TotalMarks   
    else 0  end  AS Total 
      from  UserInfo e  
 LEFT  JOIN  ViewLeave l   ON e.UserID = l.UserID 
  LEFT  JOIN SubjectType  s  ON s.SubjectID = l.SubjectID    

              Where   e.UserID = @UserD  AND 
               l.year=@Year
                 GROUP BY s.SubjectName,l.UserID, e.UserName ,TotalDays
            )ps
            pivot
            (
                SUM(Total)
                FOR SubjectName IN ([Marks1],[Marks2],[Marks3])
            ) AS pvt           

        END