当前位置: 首页 > 面试题库 >

在SQL中转置列和行的简单方法?

公羊涛
2023-03-14
问题内容

如何在SQL中简单地切换带有行的列?有没有简单的命令要转置?

即把这个结果:

        Paul  | John  | Tim  |  Eric
Red     1       5       1       3
Green   8       4       3       5
Blue    2       2       9       1

到这个:

        Red  | Green | Blue
Paul    1       8       2
John    5       4       2
Tim     1       3       9
Eric    3       5       1

PIVOT 在这种情况下似乎太复杂了。


问题答案:

您可以通过多种方法来转换此数据。在您的原始文章中,您说过PIVOT这种情况似乎太复杂了,但是可以同时使用SQL
Server中的UNPIVOTPIVOT函数来轻松地应用它。

但是,如果您无权访问这些函数,则可以使用UNION ALL来复制UNPIVOT该函数,然后使用以下CASE语句将其复制到聚合函数PIVOT

创建表:

CREATE TABLE yourTable([color] varchar(5), [Paul] int, [John] int, [Tim] int, [Eric] int);

INSERT INTO yourTable
    ([color], [Paul], [John], [Tim], [Eric])
VALUES
    ('Red', 1, 5, 1, 3),
    ('Green', 8, 4, 3, 5),
    ('Blue', 2, 2, 9, 1);

合并所有,聚合和CASE版本:

select name,
  sum(case when color = 'Red' then value else 0 end) Red,
  sum(case when color = 'Green' then value else 0 end) Green,
  sum(case when color = 'Blue' then value else 0 end) Blue
from
(
  select color, Paul value, 'Paul' name
  from yourTable
  union all
  select color, John value, 'John' name
  from yourTable
  union all
  select color, Tim value, 'Tim' name
  from yourTable
  union all
  select color, Eric value, 'Eric' name
  from yourTable
) src
group by name

参见带有演示的SQL Fiddle

UNION ALL执行与UNPIVOT通过变换列中的数据Paul, John, Tim, Eric进行分离。然后,将聚合函数sum()与该case语句一起应用以获取每个函数的新列color

Unpivot和Pivot静态版本:

SQL Server中的UNPIVOTPIVOT函数都使此转换更加容易。如果知道要转换的所有值,则可以将它们硬编码为静态版本以得到结果:

select name, [Red], [Green], [Blue]
from
(
  select color, name, value
  from yourtable
  unpivot
  (
    value for name in (Paul, John, Tim, Eric)
  ) unpiv
) src
pivot
(
  sum(value)
  for color in ([Red], [Green], [Blue])
) piv

参见带有演示的SQL Fiddle

具有的内部查询UNPIVOT执行与相同的功能UNION ALL。它获取列列表并将其转换为行,PIVOT然后执行最终转换为列。

动态数据透视图版本:

如果您有未知数量的列(Paul, John, Tim, Eric在您的示例中),然后要转换的颜色数量未知,则可以使用动态sql生成要生成的列表UNPIVOT,然后PIVOT

DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX)

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('yourtable') and
               C.name <> 'color'
         for xml path('')), 1, 1, '')

select @colsPivot = STUFF((SELECT  ',' 
                      + quotename(color)
                    from yourtable t
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query 
  = 'select name, '+@colsPivot+'
      from
      (
        select color, name, value
        from yourtable
        unpivot
        (
          value for name in ('+@colsUnpivot+')
        ) unpiv
      ) src
      pivot
      (
        sum(value)
        for color in ('+@colsPivot+')
      ) piv'

exec(@query)

参见带有演示的SQL Fiddle

动态版两种查询yourtable,然后将sys.columns表来生成物品的清单UNPIVOTPIVOT。然后将其添加到要执行的查询字符串中。动态版本的加号是如果您具有更改的列表colors和/或names它将在运行时生成列表。

所有三个查询将产生相同的结果:

| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric |   3 |     5 |    1 |
| John |   5 |     4 |    2 |
| Paul |   1 |     8 |    2 |
|  Tim |   1 |     3 |    9 |


 类似资料:
  • 问题内容: 我正在尝试将行转置为列,但是没有找到任何好的答案。 这是我想要的示例: 输入表: 输出将是: 问题答案: 您需要枚举值以对其进行透视:

  • 问题内容: 我不确定是否可以使用内置的PIG脚本完成此操作,或者我需要编写UDF代码。但实际上我有一个表,我只想在其中转置数据。 简单地说,给出: 我最终会得到: 关于如何实现此目标的任何建议? 问题答案: 用Pig不可能做到这一点,也没有任何意义。请记住,关系是一包元组,根据定义,不保证包中的元组具有任何特定顺序。您可以从开始 但是从Pig的角度来看,这与 这意味着“转置”定义不正确。以这种方式

  • 本文向大家介绍SQL Server行转列的方法解析,包括了SQL Server行转列的方法解析的使用技巧和注意事项,需要的朋友参考一下 话不多说,请看代码: 以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持呐喊教程!

  • 问题内容: 在Java中将 a 转换为a 的最简单方法是什么? 问题答案:

  • 本文向大家介绍MySQL 中行转列的方法,包括了MySQL 中行转列的方法的使用技巧和注意事项,需要的朋友参考一下 MySQL行转列操作     所谓的行转列操作,就是将一个表的行信息转化为列信息,说着可能比较笼统,这里先举个例子,如下:     上面的例子中,表1给出了三个学生的三门成绩,而表2是将表1的行记录信息(学科、姓名)转化为列信息,并根据不同的user_name进行分组显示。 1 ca

  • 问题内容: 我有一个SQL查询返回1行,其中包含多个列标题: 有没有一种方法可以将该行转换为2列,即: 这是在SQLServer 2008 r2上运行 编辑:添加一个更好的例子 来自一个简单的 类型查询。我要显示的是: 问题答案: 试试这个