首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“Transpose esque”- T/SQL

“Transpose esque”- T/SQL
EN

Stack Overflow用户
提问于 2014-02-04 18:55:57
回答 1查看 62关注 0票数 0
代码语言:javascript
复制
DECLARE @TABLE TABLE (NAME varchar(10), DOB Datetime2, Location varchar(50), Phone int)
INSERT INTO @TABLE (NAME, DOB, Location, Phone)
SELECT 'Name1','2000-01-01','USA',1234567890
UNION ALL
SELECT 'Name2','2000-01-02','CAN',0987654321

SELECT * FROM @TABLE

/*电流输出

代码语言:javascript
复制
NAME    DOB                         Location    Phone
Name1   2000-01-01 00:00:00.0000000 USA         1234567890
Name2   2000-01-02 00:00:00.0000000 CAN         987654321

期望输出

代码语言:javascript
复制
Catagory    N1              N2          ...Nn
            'NAME1'         'Name2'
DOB         '2000-01-01'    '2000-01-02'
Location    'USA'           'CAN'
Phone       1234567890      0987654321

N1,N2,...Nn都是列名(Nn =可以有动态数的“名称”,对于'Name1‘,'Name2',’Namen‘不确定如何做properly...XML?请帮帮忙!*/

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-04 19:41:11

您可以使用PIVOT函数来获得结果,但是您需要首先使用一些其他函数来获得最终产品。

首先,您需要为每一行创建一个唯一的序列(看起来不像有一个序列),这个值将用于创建新列的最终列表。您可以使用row_number()创建此值:

代码语言:javascript
复制
select name, dob, location, phone,
  row_number() over(order by name) seq
from yourtable

与Demo。一旦创建了这个唯一的值,就可以取消数据namedoblocationphone的多列。根据Server版本的不同,您可以使用un枢轴函数或交叉应用:

代码语言:javascript
复制
select 'N'+cast(seq as varchar(10)) seq,
  category, value, so
from
(
  select name, dob, location, phone,
    row_number() over(order by name) seq
  from yourtable
) src
cross apply
(
  select 'name', name, 1 union all
  select 'DOB', convert(varchar(10), dob, 120), 2 union all
  select 'Location', location, 3 union all
  select 'Phone', cast(phone as varchar(15)), 4
) c (category, value, so);

与Demo。这将以以下格式获取数据:

代码语言:javascript
复制
| SEQ | CATEGORY |      VALUE | SO |
|-----|----------|------------|----|
|  N1 |     name |      Name1 |  1 |
|  N1 |      DOB | 2000-01-01 |  2 |
|  N1 | Location |        USA |  3 |
|  N1 |    Phone | 1234567890 |  4 |

现在,您可以轻松地应用PIVOT函数:

代码语言:javascript
复制
SELECT category, n1, n2 
FROM 
(
  select 'N'+cast(seq as varchar(10)) seq,
    category, value, so
  from
  (
    select name, dob, location, phone,
      row_number() over(order by name) seq
    from yourtable
  ) src
  cross apply
  (
    select 'name', name, 1 union all
    select 'DOB', convert(varchar(10), dob, 120), 2 union all
    select 'Location', location, 3 union all
    select 'Phone', cast(phone as varchar(15)), 4
  ) c (category, value, so)
) d
pivot
(
  max(value)
  for seq in (N1, N2)
) piv
order by so;

与Demo。如果您有有限数量的值,但是如果您有一个未知数量的names,则需要使用动态SQL:

代码语言:javascript
复制
DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME('N'+cast(seq as varchar(10))) 
                    from
                    (
                      select row_number() over(order by name) seq
                      from yourtable
                    )d
                    group by seq
                    order by seq
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT category, ' + @cols + ' 
            from 
            (
              select ''N''+cast(seq as varchar(10)) seq,
                category, value, so
              from
              (
                select name, dob, location, phone,
                  row_number() over(order by name) seq
                from yourtable
              ) src
              cross apply
              (
                select ''name'', name, 1 union all
                select ''DOB'', convert(varchar(10), dob, 120), 2 union all
                select ''Location'', location, 3 union all
                select ''Phone'', cast(phone as varchar(15)), 4
              ) c (category, value, so)
            ) x
            pivot 
            (
                max(value)
                for seq in (' + @cols + ')
            ) p 
            order by so'

execute sp_executesql @query;

与Demo。它们都给出了以下结果:

代码语言:javascript
复制
| CATEGORY |         N1 |         N2 |
|----------|------------|------------|
|     name |      Name1 |      Name2 |
|      DOB | 2000-01-01 | 2000-01-02 |
| Location |        USA |        CAN |
|    Phone | 1234567890 |  987654321 |
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21560982

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档