如何将表数据转换为矩阵形式

时间:2014-08-08 09:29:26

标签: sql sql-server sql-server-2008

考虑下表

user_id  group_id  other_data
-----------------------------
1        6         foo
1        7         bar
2        7         foobar
2        8         baz
2       10         barbaz
3        8         foobaz

我需要一个查询来输出以下内容:

user_id  group_6  group_7  group_8  group_9  group_10
-----------------------------------------------------
1        x        x
2                 x        x                 x
3                          x

换句话说:概述,显示用户所属的组。

这在SQL中可行吗?我知道这可能违背了数据库的意图(它比提取数据更具说明性)但如果我不必摆弄第一张表格中原始格式的长列表,那就太棒了。

我已经搜索了"transpose rows to columns SQL Server"等搜索引擎,我相信我需要pivot(),但无法弄清楚如何。

非常感谢任何帮助: - )

2 个答案:

答案 0 :(得分:2)

方法 - 1:

您必须通过PIVOT动态查询

来实现此目的

可能是这样的。

DECLARE @Cols AS NVARCHAR(MAX),@Query  AS NVARCHAR(MAX);

SET @Cols = STUFF((SELECT Distinct ',' + QUOTENAME(C.group_id) 
            FROM table1 C
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')

SET @Query = 'SELECT user_id, ' + @Cols + ' FROM 
              (
                SELECT user_id,other_data,group_id
                FROM table1
              ) X
              Pivot 
              (
                MAX(other_data)
                FOR group_id IN (' + @cols + ')
              ) P '


Execute (@Query)

Fiddle Demo

输出

USER_ID  6     7      8       10
1        foo   bar   (null)  (null)
2       (null) foobar baz    barbaz
3       (null) (null) foobaz (null)

方法 - 2:

如果您的group_id ID已修复,则可以继续正常pivot

SELECT  * 
FROM  table1 T
PIVOT
   ( 
    MAX(other_data) FOR group_id IN ([6],[7],[8],[9],[10]) 
   ) P;

输出

USER_ID  6     7      8       9      10
1        foo   bar   (null)  (null)  (null)
2       (null) foobar baz    (null)  barbaz
3       (null) (null) foobaz (null)  (null)

Fiddle Demo

答案 1 :(得分:2)

你需要PIVOT数据:

Demo SQL Fiddle

<强>设定:

CREATE TABLE Table1
    ([user_id] int, [group_id] int, [other_data] varchar(6))
;

INSERT INTO Table1
    ([user_id], [group_id], [other_data])
VALUES
    (1, 6, 'foo'),
    (1, 7, 'bar'),
    (2, 7, 'foobar'),
    (2, 8, 'baz'),
    (2, 10, 'barbaz'),
    (3, 8, 'foobaz');

SQL Pivot:

;WITH PivotSource
AS
(
    SELECT   t.[user_id], t.[group_id]  
     FROM    Table1 t
)

SELECT  * 
FROM    PivotSource  
 PIVOT   ( max(group_id) FOR group_id IN ([6],[7],[8],[9],[10]) ) pvt;

<强>输出:

| USER_ID |      6 |      7 |      8 |      9 |     10 |
|---------|--------|--------|--------|--------|--------|
|       1 |      6 |      7 | (null) | (null) | (null) |
|       2 | (null) |      7 |      8 | (null) |     10 |
|       3 | (null) | (null) |      8 | (null) | (null) |