将行转换为多列

时间:2013-12-17 10:47:31

标签: sql-server sql-server-2012

我有这样的结果

SubjectId   ReasonId    TypeId

1           1           0
1           1           0
1           2           0
1           2           0
1           3           0
1           4           1
1           4           1
1           6           1
1           6           1
2           1           0
...
...
...

但是,我必须创建如下的报告:

SubjectId   ReasonId(Type0)   Count(Type0)   ReasonId(Type1)   Count(Type1)

1           1                 2              4                 2
1           2                 2              6                 2
1           3                 1              5                 0
2           1                 1              4                 0
2           2                 0              5                 0
2           3                 0              6                 0

让我解释一下:

不是在标准视图中显示结果,而是每条记录都是新行,我必须将结果分成两组:

第一组修复了每行SubjectId三行,值为TypeId = 0,对于每个原因(1,2,3)我必须显示特定原因的行数。 ReasonId必须按行数降序排序。

第二组位于第一组右侧,故事相同,而TypeId = 0则有TypeId = 1。需要相同的降序。

因此,每个ReasonId对于每个ReasonId只有三行(对于类型0,有原因1,2,3,对于类型1,有原因4,5,6)。

如果某个主题因任何原因没有行,我必须写0。

1 个答案:

答案 0 :(得分:0)

  

因此,每个SubjectId的每个SubjectId都有三行(for   类型0有原因1,2,3,对于类型1有原因4,   5,6)。

这是数据库需要的关键信息。将这些规则编码到表中并将其交叉连接到数据表。

    SELECT
      [SubjectId],
      [ReasonID(Type0)],
      SUM(CASE WHEN [ReasonId] = [ReasonID(Type0)] THEN 1 ELSE 0 END) AS [Count(Type0)],
      [ReasonID(Type1)],
      SUM(CASE WHEN [ReasonId] = [ReasonID(Type1)] THEN 1 ELSE 0 END) AS [Count(Type1)]
    FROM MyTable S
    CROSS JOIN (VALUES (1,4),(2,5),(3,6)) X([ReasonID(Type0)],[ReasonID(Type1)])
    GROUP BY [SubjectId],[ReasonID(Type0)],[ReasonID(Type1)]

独立排序每个原因:

WITH SortedCounts AS (
  SELECT
    S.[SubjectId],T.[TypeId],T.[ReasonId],
    SUM(CASE WHEN S.[ReasonId] = T.[ReasonId] AND S.[TypeId] = T.[TypeId] THEN 1 ELSE 0 END) AS [Count],
    ROW_NUMBER() OVER(
      PARTITION BY S.[SubjectId],T.[TypeId]
      ORDER BY SUM(CASE WHEN S.[ReasonId] = T.[ReasonId] AND S.[TypeId] = T.[TypeId] THEN 1 ELSE 0 END) DESC, T.[ReasonId] ASC
    ) [SortOrder]
  FROM MyTable S
  CROSS JOIN (VALUES(0,1),(0,2),(0,3),(1,4),(1,5),(1,6)) T([TypeId],[ReasonId])
  GROUP BY S.[SubjectId],T.[TypeId],T.[ReasonId]
)
SELECT
  [SubjectId],
  MIN(CASE WHEN [TypeId] = 0 THEN [ReasonId] END) AS [ReasonId(Type0)],
  MIN(CASE WHEN [TypeId] = 0 THEN [Count]    END) AS [Count(Type0)],
  MIN(CASE WHEN [TypeId] = 1 THEN [ReasonId] END) AS [ReasonId(Type1)],
  MIN(CASE WHEN [TypeId] = 1 THEN [Count]    END) AS [Count(Type1)]
FROM SortedCounts T
GROUP BY [SubjectId],[SortOrder]
ORDER BY [SubjectId],[SortOrder]