SQL Server Pivot或UnPivot如此困惑

时间:2016-06-28 09:25:11

标签: sql-server

我正在使用SQL Server数据库创建报告。但不幸的是,我无法弄清楚如何做到这一点。

这是我的数据库结构:

CREATE TABLE #myTable
(
    [ForYear] [smallint] NOT NULL,
    [ForMonth] [tinyint] NOT NULL,
    [TrainingDoneThisMonth] [bit] NULL,
    [FoodQualityStatus] [bit] NULL,
    [NoOfAllDrugTests] [int] NULL,
    [NoOfAllAlcoholTests] [int] NULL
)

INSERT INTO #myTable 
VALUES (2016, 1, 1, 0, 5, 10), (2016, 2, 0, 1, 15, 5),
       (2016, 3, 1, 0, 20, 15), (2016, 4, 0, 1, 5, 25),
       (2016, 5, 1, 0, 10, 30)

我需要以下格式报告。其中列名称转换为行,并且还会转换相应的值。

Report sample

我尝试过枢轴和非透视但是我无法得到理想的结果请帮助。

这就是我的尝试:

select 1,2,3
from
(
  select NoOfAllAlcoholTests,ForMonth
  from #myTable
) d
pivot
(
  SUM(NoOfAllAlcoholTests)
  for forMonth in ([1],[2],[3])
) piv;

2 个答案:

答案 0 :(得分:2)

UNPIVOT然后PIVOT:

SELECT  Objective, 
        [January],
        [February],
        [March],
        [April],
        [May],
        CASE WHEN Objective IN ('NoOfAllDrugTests','NoOfAllAlcoholTests') THEN CAST([January]+[February]+[March]+[April]+[May] as nvarchar(10))
             ELSE CAST([January]+[February]+[March]+[April]+[May] as nvarchar(10)) +' True, ' +
             CAST(5 -( [January]+[February]+[March]+[April]+[May]) as nvarchar(10)) +' False'
              END as FinalTotal
FROM (
    SELECT *
    FROM (
        SELECT  DATENAME(month,DATEADD(month,[ForMonth]-1,'1970-01-01')) as d,
                CAST([TrainingDoneThisMonth] as int) as [TrainingDoneThisMonth],
                CAST([FoodQualityStatus] as int) as [FoodQualityStatus],
                [NoOfAllDrugTests],
                [NoOfAllAlcoholTests]
        FROM #myTable
        ) d
    UNPIVOT (
      [VALUES] FOR [Objective] in ([TrainingDoneThisMonth],[FoodQualityStatus],[NoOfAllDrugTests],[NoOfAllAlcoholTests])
    ) unpvt
) as p
PIVOT (
    SUM([VALUES]) FOR d IN ([January],[February],[March],[April],[May])
) as pvt

输出:

Objective               January February    March   April   May FinalTotal
FoodQualityStatus       0       1           0       1       0   2 True, 3 False
NoOfAllAlcoholTests     10      5           15      25      30  85
NoOfAllDrugTests        5       15          20      5       10  55
TrainingDoneThisMonth   1       0           1       0       1   3 True, 2 False

答案 1 :(得分:1)

您需要结合使用unpivot和pivot来执行此操作

;WITH data
     AS (SELECT *,
                Sum(Cast([TrainingDoneThisMonth] AS INT))OVER() AS Training_True,
                Sum(Cast(FoodQualityStatus AS INT))OVER() AS FoodQuality_True,
                Count(1)OVER() AS Total_count,
                Sum([NoOfAllDrugTests])OVER() AS sum_NoOfAllDrug,
                Sum([NoOfAllAlcoholTests])OVER() AS sum_NoOfAllAlcohol
         FROM   #myTable),
     un_pivot
     AS (SELECT ForYear,
                Choose(ForMonth, 'Jan', 'Feb', 'Mar', 'Apr')        AS Month_name,
                data,
                name,
                Training_True = Cast(Training_True AS VARCHAR(20)),
                FoodQuality_True = Cast(FoodQuality_True AS VARCHAR(20)),
                Cast(Total_count - Training_True AS VARCHAR(20))    AS Training_false,
                Cast(Total_count - FoodQuality_True AS VARCHAR(20)) AS FoodQuality_false,
                sum_NoOfAllDrug,
                sum_NoOfAllAlcohol
         FROM   data
                CROSS apply (VALUES ([TrainingDoneThisMonth],'TrainingDoneThisMont'),
                                    (FoodQualityStatus,'FoodQualityStatus'),
                                    (NoOfAllDrugTests,'NoOfAllDrugTests'),
                                    (NoOfAllAlcoholTests,'NoOfAllAlcoholTests')) cs (data, name))
SELECT name,
       [Jan],
       [Feb],
       [Mar],
       [Apr],
       CASE name
         WHEN 'TrainingDoneThisMont' THEN Training_True + ' True, ' + Training_false+ ' False'
         WHEN 'FoodQualityStatus' THEN FoodQuality_True + ' True, '+ FoodQuality_false + ' False'
         WHEN 'NoOfAllDrugTests' THEN Cast(sum_NoOfAllDrug AS VARCHAR(20))
         WHEN 'NoOfAllAlcoholTests' THEN Cast(sum_NoOfAllAlcohol AS VARCHAR(20))
       END
FROM   un_pivot
       PIVOT ( Max(data)
             FOR Month_name IN ([Jan],
                                [Feb],
                                [Mar],
                                [Apr])) pv