SQL服务器在多列上进行透视 - 另一个维度

时间:2015-01-23 04:43:05

标签: sql-server

我正在尝试在多列上使用数据透视表。目前,我只用一列即可实现这一目标。我当前的方法返回:

Membership  Item1
DO1          400
Neither       21
Plan A        69
Plan B        53

但这是我想要实现的目标:

Membership  Item1   Item2   Item3   Item3    Item4    Item5
DO1          30     300      25        14       10      144
Neither      35     250      30        30       5       125
Plan A       50     100      25        25       5       254
Plan B       100     25      15        25       4       123

这是我的代码

WITH CTE_SQL
AS 
(
    SELECT CaseId
          ,Item1 AS Number1
          ,[Membership] -- ,Item2 AS Number2,Item3 AS Number3,Item4 AS Number4,Item5 AS Number5
          FROM TABLE1
          WHERE [Membership] IS NOT NULL
)
SELECT [Membership]
       ,Item1 --,Item2--,Item3 AS 'Item3',Item4 AS 'Item4',Item5 AS 'Item5'
FROM 
(
    SELECT CaseId
          ,Number1
          ,[Membership] --,[Item2],[Item3],[Item4],[Item5]
          FROM CTE_SQL
) AS p
PIVOT
(
    COUNT(CaseId) 
    FOR Number1 IN (Item1)
) AS pvt
ORDER BY [Membership]

有什么见解? 更新此处是表架构

ColumnName  DataType    Allow Nulls
..........  ........    ...........
CaseId    nvarchar(50)      No
Membership  nvarchar(50)    Yes
Item1      nvarchar(50)     Yes
Item2      nvarchar(50)     Yes
Item3      nvarchar(50)     Yes
Item4     nvarchar(50)      Yes
Item5     nvarchar(50)      Yes

所以这是我上一次的更新。这是我的源数据:

CREATE TABLE TABLE1
(CASENumber NVARCHAR(50),Membership NVARCHAR(50),Item1 NVARCHAR(50),Item2 NVARCHAR(50),Item3 NVARCHAR(50),Item4 NVARCHAR(50),Item5 NVARCHAR(50))

INSERT INTO TABLE1
SELECT 'Case001', 'D01','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case002', 'D01','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case003', 'Neither','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case004', 'Neither','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case005', 'Neither','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case001', 'PlanA','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case002', 'PlanA','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case003', 'PlanB','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case004', 'PlanB','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case005', 'PlanB','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case001', 'D01','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case002', 'D01','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case003', 'Neither','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case004', 'Neither','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case005', 'Neither','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case001', 'PlanA','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case002', 'PlanA','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case003', 'PlanB','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case004', 'PlanB','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case005', 'PlanB','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case003', 'PlanB','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case004', 'PlanB','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case005', 'PlanB','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case005', 'PlanB','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case001', 'D01','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case002', 'D01','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case003', 'Neither','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case004', 'Neither','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case005', 'PlanB','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case005', 'PlanB','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case001', 'PlanB','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case002', 'D01','Gold','Silver','Diamond','Steel','Wood'
UNION ALL
SELECT 'Case003', 'Neither','Gold','Silver','Diamond','Steel','Wood'

在这里,我的代码和输出到目前为止一直困在我们身上:

WITH CTE_SQL
  AS
  (
      SELECT CASENumber,Item1 AS Number1,[Membership]--,Item2 AS Number2,
      Item3 AS  Number3,Item4 Number4,Item5 AS Number5
      FROM  dbo.TABLE1
      WHERE [Membership] IS NOT NULL 

  )
  SELECT Membership,Gold as 'Item1' --,Item2--,Item3 AS 'Item3',
  Item4 AS 'Item4',Item5 AS 'Item5' 
  FROM 
  (
      SELECT CaseNumber,Number1,Membership--,[Item2],[Item3],[Item4],[Item5]
      FROM  CTE_SQL 
   ) AS p 
   PIVOT 
   (
      COUNT(CASENumber)
      FOR Number1 in(Gold)  
   ) as pvt

当前输出

Membership  Item1
.........   .....
D01           7
Neither       9
PlanA         4
PlanB        13

预期输出

Membership  Item1   Item2   Item3   Item4   Item5
..........  .....   .....   .....   .....   .....
D01         7        7        7       7       7
Neither     9        9       9        9       9
PlanA       4        4        4       4       4
PlanB       13      13        13      13      13

请注意,items1列下的所有元素都是黄金。这同样适用于分别为SilverDiamondSteelWood的第2-5项。

1 个答案:

答案 0 :(得分:0)

您需要动态数据透视才能获得结果。

声明变量以获取pivot

的列
 DECLARE @cols NVARCHAR (MAX)

 SELECT @cols = COALESCE (@cols + ',[' + Number1 + ']', '[' + Number1 + ']')
                   FROM    (SELECT DISTINCT Number1 FROM #TEMP) PV 
                   ORDER BY Number1

现在转动查询

DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT * FROM 
             (
                 SELECT Membership, Number1, 
                 -- Get the count here
                 COUNT(CASEID) OVER(PARTITION BY Membership,Number1) CNT 
                 FROM #TEMP
                 WHERE Membership IS NOT NULL
             ) x
             PIVOT 
             (
                 MIN(CNT)
                 FOR Number1 IN (' + @cols + ')
            ) p
            ORDER BY Membership;' 

EXEC SP_EXECUTESQL @query

编辑:

根据您的更新,如果您需要为每个成员计算CaseId,您可以使用以下查询

;WITH CTE AS
(
    SELECT DISTINCT Membership, 
    COUNT(CASEID) OVER(PARTITION BY Membership) CNT 
    FROM TABLE1
    WHERE Membership IS NOT NULL
)
SELECT Membership,CNT AS Item1,CNT AS Item2,CNT AS Item3,CNT AS Item3,CNT AS  Item4,CNT AS Item5
FROM CTE

编辑2:

亲爱的朋友。这是一个简单的过程。我们可以在没有旋转的情况下完成。我们可以在PARTITION BY()中使用Sql Server方法,它会为每个CASENUMBER获得Membership的总计数。

SELECT DISTINCT [Membership],
COUNT(Item1) OVER(PARTITION BY [Membership]) AS Item1,
COUNT(Item2) OVER(PARTITION BY [Membership]) AS Item2,
COUNT(Item3) OVER(PARTITION BY [Membership]) AS Item3,
COUNT(Item4) OVER(PARTITION BY [Membership]) AS Item4,
COUNT(Item5) OVER(PARTITION BY [Membership]) AS Item5
FROM  TABLE1
WHERE [Membership] IS NOT NULL 
ORDER BY MEMBERSHIP

<强> RESULT

x-------------x-----------x----------x----------x---------x---------x
|  Membership |   Item1   |   Item2  |   Item3  |  Item4  |  Item5  |
x-------------x-----------x----------x----------x---------x---------x           
|    D01      |      7    |    7     |     7    |    7    |     7   |
|    Neither  |      9    |    9     |     9    |    9    |     9   |
|    Plan A   |      4    |    4     |     4    |    4    |     4   |
|    Plan B   |     13    |    13    |    13    |   13    |    13   |
x-------------x-----------x----------x----------x---------x---------x