如何在 Sql Server 2008 R2 中将列转换为行?

Posted

技术标签:

【中文标题】如何在 Sql Server 2008 R2 中将列转换为行?【英文标题】:How to Convert Columns to Rows in Sql Server 2008 R2? 【发布时间】:2013-12-08 10:34:14 【问题描述】:

我有一张这样的桌子

结果应该是这样的

我对 Pivot 和 unpivot 和交叉应用有点困惑。任何人都可以帮助我。

【问题讨论】:

【参考方案1】:

您正在旋转两列 (department, [check/uncheck])。据我所知,这意味着您不能使用 SQL Server 的 pivot 语法。

一种方法是在子查询中“取消透视”(又名“规范化”)checked。然后,您可以在外部查询中“旋转”(也称为“非规范化”)tools 列:

select  department
,       [Check/Uncheck]
,       sum(case when tools = 'engine' then nr else 0 end) as engine
,       sum(case when tools = 'oils' then nr else 0 end) as oils
,       sum(case when tools = 'grease' then nr else 0 end) as grease
,       sum(case when tools = 'sounds' then nr else 0 end) as sounds
,       sum(case when tools = 'wapers' then nr else 0 end) as wapers
from    (
        select  department
        ,       tools
        ,       'Checked' as [Check/Uncheck]
        ,       checked as nr
        from    dbo.YourTable
        union all
        select  department
        ,       tools
        ,       'Unchecked'
        ,       unchecked
        from    dbo.YourTable
        ) as SubQueryAlias
group by
        Department
,       [Check/Uncheck]
order by
        Department
,       [Check/Uncheck]

Live example at SQL Fiddle.

【讨论】:

【参考方案2】:

您可以使用 PIVOT 函数来获取结果,但首先您需要取消旋转 uncheckedchecked 列。由于您使用的是 SQL Server 2008r2,因此您可以使用 CROSS APPLY 将列取消透视为多行。

CROSS APPLY 的基本语法是:

select department, tools,
  [check/uncheck],
  value
from yourtable
cross apply
(
  values
    ('checked', checked),
    ('unchecked', unchecked)
) c([check/uncheck], value);

请参阅Demo,这会将您的数据转换为以下格式:

| DEPARTMENT |  TOOLS | CHECK/UNCHECK | VALUE |
|------------|--------|---------------|-------|
|   Maintain | engine |       checked |     0 |
|   Maintain | engine |     unchecked |     0 |
|   Maintain |   oils |       checked |     0 |
|   Maintain |   oils |     unchecked |     2 |

数据转换成这种格式后,您就可以使用 PIVOT 函数将您的tools 转换为列:

select department,
  [check/uncheck],
  engine, oils, grease, sounds, wapers
from
(
  select department, tools,
    [check/uncheck],
    value
  from yourtable
  cross apply
  (
    values
      ('checked', checked),
      ('unchecked', unchecked)
  ) c([check/uncheck], value)
) d
pivot
(
  sum(value)
  for tools in (engine, oils, grease, sounds, wapers)
) piv
order by department;

见SQL Fiddle with Demo。这将给出以下结果:

| DEPARTMENT | CHECK/UNCHECK | ENGINE | OILS | GREASE | SOUNDS | WAPERS |
|------------|---------------|--------|------|--------|--------|--------|
|   Maintain |       checked |      0 |    0 |      5 |      0 |      0 |
|   Maintain |     unchecked |      0 |    2 |      1 |      0 |      0 |
| Operations |       checked |      1 |    2 |      1 |      5 |      0 |
| Operations |     unchecked |      0 |    1 |      2 |      1 |      2 |

【讨论】:

以上是关于如何在 Sql Server 2008 R2 中将列转换为行?的主要内容,如果未能解决你的问题,请参考以下文章