我有一个包含多行的SQL表,我希望将其放入一行中有多列

时间:2013-04-19 16:41:17

标签: sql sql-server pivot

我有一个SQL表,它为用户提供了多行数据。我想查询该数据并为每个用户返回一行。所以我想取多行并将它们组合成一行,多行。这可能吗?

以下是我目前的内容

UserID   Value
8111     396285
8111     812045789854
8111     Secretary

以下是我的目标

UserID     Column1     Column2        Column3
8111       396285      812045789854   Secretary

2 个答案:

答案 0 :(得分:2)

您可以使用PIVOT功能获取结果。我使用row_number()函数生成将转换为列的值。

如果您知道提前有多少值,那么您可以对查询进行硬编码:

select userid, Col1, Col2, Col3
from
(
  select userid, value,
    'Col'+cast(row_number() over(partition by userid 
                                  order by (select 1)) as varchar(10)) rn
  from yt
) d
pivot
(
  max(value)
  for rn in (Col1, Col2, Col3)
) piv;

请参阅SQL Fiddle with Demo

如果您有未知数量的值,则可以使用动态SQL:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME('Col'+cast(row_number() over(partition by userid 
                                                                                    order by (select 1)) as varchar(10))) 
                    from yt
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT userid,' + @cols + ' 
             from 
             (
                select userid, value,
                  ''Col''+cast(row_number() over(partition by userid 
                                                order by (select 1)) as varchar(10)) rn
                from yt
            ) x
            pivot 
            (
                max(value)
                for rn in (' + @cols + ')
            ) p '

execute(@query);

SQL Fiddle with Demo。两者都给出了结果:

| USERID |   COL1 |         COL2 |      COL3 |
----------------------------------------------
|   8111 | 396285 | 812045789854 | Secretary |

答案 1 :(得分:0)

如果您不能或不想使用PIVOT / UNPIVOT,则另一个选项是将列逐个加入用户:

DECLARE @Users TABLE(
    UserID int NOT NULL
)

INSERT INTO @Users (UserID) VALUES (1)
INSERT INTO @Users (UserID) VALUES (2)
INSERT INTO @Users (UserID) VALUES (3)

DECLARE @AnyTable TABLE(
    UserID int NOT NULL,
    FieldNo int NOT NULL,
    Value varchar(50) NULL
)

INSERT INTO @AnyTable (UserID, FieldNo, Value) VALUES (1, 1, 'abc')
INSERT INTO @AnyTable (UserID, FieldNo, Value) VALUES (1, 2, 'def')
INSERT INTO @AnyTable (UserID, FieldNo, Value) VALUES (1, 3, 'ghi')
INSERT INTO @AnyTable (UserID, FieldNo, Value) VALUES (2, 1, '123')
INSERT INTO @AnyTable (UserID, FieldNo, Value) VALUES (2, 3, '789')

SELECT u.UserID,
    col1.Value as Column1,
    col2.Value as Column2,
    col3.Value as Column3
FROM @Users u
LEFT JOIN @AnyTable col1
    ON col1.UserID = u.UserID
    AND col1.FieldNo = 1
LEFT JOIN @AnyTable col2
    ON col2.UserID = u.UserID
    AND col2.FieldNo = 2
LEFT JOIN @AnyTable col3
    ON col3.UserID = u.UserID
    AND col3.FieldNo = 3

结果将是:

UserID   Column1   Column2   Column3
 1        abc       def       ghi
 2        123       NULL      789
 3        NULL      NULL      NULL