使用PIVOT命令在SQL SERVER中的行(将NULL值替换为0并显示所有值的SUM)

时间:2012-09-21 09:21:37

标签: sql sql-server

我想在Sql Server中向列显示行。我已经看到了其他问题,但这些列在枢轴中是硬编码的,但我的列将是动态的。到目前为止我所取得的成就。如截图所示,我可以将行转换为列,但很少有东西我无法完成..需要你的帮助

  1. 在所有列中将NULL替换为0
  2. 需要添加1个列,该列将显示除companyID
  3. 之外的所有列的总和

    我的SQL代码:

    DECLARE @Columns VARCHAR(MAX)
    DECLARE @Convert VARCHAR(MAX)
    
    SELECT  @Columns = STUFF((
               SELECT '],[' + ErrClassfn
                 from ArchimedesTables.dbo.PM_ErrClassificationSetup
                WHERE CONVERT(VARCHAR(10), ISNULL(EndDate, GETDATE()), 101) 
                              Between CONVERT(VARCHAR(10), GETDATE(), 101)
                              AND     CONVERT(VARCHAR(10), GETDATE(), 101)
                ORDER BY '],[' + CONVERT(VARCHAR(MAX), ID) ASC
                  FOR
                      XML PATH('')
               ), 1, 2, '') + ']'
    
    SET @Convert = 'SELECT  * INTO #mynewTable FROM
    (
        SELECT COUNT(WQ.ErrClassfnID) as ErrorCount, UPPER(WQ.CompanyID) as CompanyID, 
               PME.ErrClassfn as ErrorName
          FROM Version25.dbo.WF_Quality AS WQ
          LEFT JOIN ArchimedesTables.dbo.PM_ErrClassificationSetup as PME
               ON WQ.ErrClassfnID = PME.ID
         GROUP BY
              UPPER(CompanyID), ErrClassfn
    ) Quality PIVOT ( SUM(ErrorCount)  For ErrorName IN (' + @Columns
        + ')) as PivotTable  SeLeCt * FROM #mynewTable'
    
    EXEC(@Convert)
    

    enter image description here

1 个答案:

答案 0 :(得分:2)

您可以更改Dynamic Pivot的列名等,类似于:

DECLARE @ColumnsNull VARCHAR(MAX)
DECLARE @Columns VARCHAR(MAX)
DECLARE @Convert VARCHAR(MAX)

SELECT  @ColumnsNull = STUFF((SELECT ', IsNull(' + QUOTENAME(ErrClassfn) +', 0) as ['+ rtrim(ErrClassfn)+']' 
                   from ArchimedesTables.dbo.PM_ErrClassificationSetup
                   WHERE CONVERT(VARCHAR(10), ISNULL(EndDate, GETDATE()), 101) 
                                  Between CONVERT(VARCHAR(10), GETDATE(), 101)
                                  AND     CONVERT(VARCHAR(10), GETDATE(), 101)
                   ORDER BY ID ASC
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

SELECT  @Columns = STUFF((
           SELECT '],[' + ErrClassfn
             from ArchimedesTables.dbo.PM_ErrClassificationSetup
            WHERE CONVERT(VARCHAR(10), ISNULL(EndDate, GETDATE()), 101) 
                          Between CONVERT(VARCHAR(10), GETDATE(), 101)
                          AND     CONVERT(VARCHAR(10), GETDATE(), 101)
            ORDER BY '],[' + CONVERT(VARCHAR(MAX), ID) ASC
              FOR
                  XML PATH('')
           ), 1, 2, '') + ']'


SET @Convert = 'SELECT  CompanyID, '+ @ColumnsNull + '
                INTO #mynewTable 
                FROM
                (
                    SELECT COUNT(WQ.ErrClassfnID) as ErrorCount, UPPER(WQ.CompanyID) as CompanyID, 
                           PME.ErrClassfn as ErrorName
                      FROM Version25.dbo.WF_Quality AS WQ
                      LEFT JOIN ArchimedesTables.dbo.PM_ErrClassificationSetup as PME
                           ON WQ.ErrClassfnID = PME.ID
                     GROUP BY
                          UPPER(CompanyID), ErrClassfn
                ) Quality PIVOT ( SUM(ErrorCount)  For ErrorName IN (' + @Columns
                    + ')) as PivotTable  SeLeCt * FROM #mynewTable'

EXEC(@Convert)

我建议编写查询并首先使列工作,然后将数据添加到#temp表中。以这种方式调试会更容易。

您也可以使用相同的方式创建SUM()字段,然后动态构建它,然后在最终SELECT中添加它:

所以你可以添加到最终SELECT

这样的东西
SELECT  @ColumnsTotal = STUFF((SELECT '+' + QUOTENAME(ErrClassfn) 
                   from ArchimedesTables.dbo.PM_ErrClassificationSetup
                   WHERE CONVERT(VARCHAR(10), ISNULL(EndDate, GETDATE()), 101) 
                                  Between CONVERT(VARCHAR(10), GETDATE(), 101)
                                  AND     CONVERT(VARCHAR(10), GETDATE(), 101)
                   ORDER BY ID ASC
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')