在SQL中使用“PIVOT”

时间:2013-11-18 21:28:54

标签: c# sql sql-server

我回过头来做了这个问题。

SQL Server making rows into columns

基本上,回答的人非常清楚地解释了我需要做什么。但是,我遇到了一个问题

aID| status | group   |
-----------------------
1  |   acti |  group1 |
2  |   inac |  group2 |
A3  |   acti |  group1 |

第二张表:此表已修复。它有大约20个值,ID都是数字

atID| traitname  |
------------------
 1  |   trait1   |
 2  |   trait2   |
 3  |   trait3   |

第三表:该表用于识别第一个表中资产的特征。与上表中的字段同名的字段显然是链接的。

tID|   aID  |   atID |   trait   |
----------------------------------
1  |   1    |    1   |   NAME    |
2  |   1    |    2   |   INFO    |
3  |   2    |    3   |   GOES    |
4  |   2    |    1   |   HERE    |

现在,用户希望程序以下列格式输出数据:

aID| status | group  | trait1 | trait2 | trait 3
-------------------------------------------------
1  |  acti  |  group1 |  NAME |  INFO  | NULL
2  |  inac  |  group2 |  HERE |  NULL  | GOES
A3 |  acti  |  group1 |  NULL |  NULL  | NULL

现在,问题在于,正如您所看到的,A3没有特征。在最终视图中,我希望A3在特征中看起来完全为空。但它根本没有出现,即使它存在。有谁知道如何解决这个问题?

以下是我正在使用的查询:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(traitname) 
                    from Table2
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT aid, status, [group],' + @cols + ' 
            from 
            (
              select t1.aid,
                t1.status,
                t1.[group],
                t2.traitname,
                t3.trait
              from table1 t1
              inner join table3 t3
                on t1.aid = t3.aid
              inner join table2 t2
                on t3.atid = t2.atid
            ) x
            pivot 
            (
                max(trait)
                for traitname in (' + @cols + ')
            ) p '

execute sp_executesql @query;

1 个答案:

答案 0 :(得分:1)

问题是你在桌子上使用INNER JOININNER JOIN返回两个表中具有匹配数据的所有行。

由于您要返回Table1的所有内容,因此您将更改查询以使用LEFT JOIN代替INNER JOIN

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(traitname) 
                    from Table2
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT aid, status, [group],' + @cols + ' 
            from 
            (
              select t1.aid,
                t1.status,
                t1.[group],
                t2.traitname,
                t3.trait
              from table1 t1
              left join table3 t3
                on t1.aid = t3.aid
              left join table2 t2
                on t3.atid = t2.atid
            ) x
            pivot 
            (
                max(trait)
                for traitname in (' + @cols + ')
            ) p '

execute sp_executesql @query;

作为旁注,很难说出连接列上的数据类型是什么。由于Table1.aid值,您的A3列似乎是varchar,但您的Table3.aid列看起来是int。如果您的数据类型不同,那么您需要在联接上投射数据类似于 - on t1.aid = cast(t3.aid as varchar(10))