【问题标题】:How to use SQL Server 2005 Pivot based on lookup table如何使用基于查找表的 SQL Server 2005 Pivot
【发布时间】:2014-12-13 12:43:56
【问题描述】:

表[状态]有以下数据:

ID  Status
1   PaymentPending
2   Pending
3   Paid
4   Cancelled
5   Error

======================================

数据表结构如下:

ID    WeekNumber StatusID
1       1           1
2       1           2
3       1           3
4       2           1
5       2           2
6       2           2
7       2           3

寻找支点

Week #      PaymentPending     Pending     Paid    Cancelled
Week 1            1                1         1         0
Week 2            1                2         1         0

【问题讨论】:

    标签: sql sql-server sql-server-2005 pivot


    【解决方案1】:

    枢轴可能如下所示:

    SELECT * FROM 
        (SELECT 
           'Week ' + CAST(D.WeekNumber AS varchar(2)) [Week #], 
           S.Status 
        FROM DataTbl D
        INNER JOIN Status S ON D.StatusID = S.ID
        ) Derived
    PIVOT 
    (
    COUNT(Status) FOR Status IN 
      ([PaymentPending], [Pending], [Paid], [Cancelled]) -- add [Error] if needed
    ) Pvt
    

    如果您希望Status表中的项目数发生变化,您可能需要考虑使用动态透视来生成列标题。像这样的:

    DECLARE @sql AS NVARCHAR(MAX)
    DECLARE @cols AS NVARCHAR(MAX)
    
    SELECT @cols = ISNULL(@cols + ',','') + QUOTENAME(Status)
    FROM (SELECT ID, Status FROM Status) AS Statuses ORDER BY ID
    
    SET @sql =
      N'SELECT * FROM 
           (SELECT ''Week '' + CAST(D.WeekNumber AS varchar(2)) [Week #], S.Status
        FROM Datatbl D
        INNER JOIN Status S ON D.StatusID = S.ID) Q
        PIVOT (
           COUNT(Status)
              FOR Status IN (' + @cols + ')
            ) AS Pvt'
    
    EXEC sp_executesql @sql;
    

    Sample SQL Fiddle

    【讨论】:

    • 虽然其他解决方案也是有效的,但这个带有动​​态 sql 的解决方案为我的需求提供了最佳解决方案。谢谢
    【解决方案2】:
    SELECT 'Week '+CAST(coun.WeekNumber AS VARCHAR(10)) [Week #],[PaymentPending],[Pending],[Paid],[Cancelled],[Error] FROM 
    (SELECT [WeekNumber],[Status] FROM dbo.WeekDetails 
    INNER JOIN [dbo].[Status] AS s
    ON [dbo].[WeekDetails].[StatusID] = [s].[ID]) AS wee
    PIVOT (COUNT(wee.[Status]) FOR wee.[Status]
    IN  ([PaymentPending],[Pending],[Paid],[Cancelled],[Error])) AS Coun
    

    【讨论】:

      【解决方案3】:

      您可以将基于 CASE 的聚合与 GROUP BY 一起使用

      SELECT 'Week ' + cast(WeekNumber as varchar(10)) as 'Week#',
             SUM ( CASE WHEN StatusId =1 THEN 1 else 0 end) as 'PaymentPending',
             SUM ( CASE WHEN StatusId =2 THEN 1 else 0 end) as 'Pending',
             SUM ( CASE WHEN StatusId =3 THEN 1 else 0 end) as 'Paid',
             SUM ( CASE WHEN StatusId =4 THEN 1 else 0 end) as 'Cancelled'
      FROM DataTbl D
      GROUP BY 'Week ' + cast(WeekNumber as varchar(10))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多