转换表中列的行

时间:2014-03-26 15:13:15

标签: sql-server

我正在尝试旋转表格的可视化,将行显示为列而不进行任何聚合。

假设我有这张表

create table user  
    id       int,  
    name     nvarchar(100),  
    company  nvarchar(100),  
    division nvarchar(100),  
    city     nvarchar(100)

可以使用此选择

检索
select name,company division, city from user order by id  

给了我这个结果

john    Company1   division1   City1  
Peter   Company2   division2   City2  
Mary    Company3   division3   City3 
.
.

但我需要的是将每一行显示为一列,第一列显示字段名称,如下所示

Name     john        Peter      Mary       ....  
Company  Company1    Company2   Company3   ....  
Division division1   division2  division3  ....  
City     City1       City2      City3      ....

我怎样才能做到这一点?我尝试使用这个univot

select col,value
from
    (select cast(name as varchar) as name,
            cast(Company as varchar) as company,
            cast(Division as varchar) as division
            cast(City as varchar) as city
        from user) p
    unpivot
    (value for col in (name,company,division,city)) as unpvt

但这就是我得到的(注意:我想要同一行中的所有名字)

name     john  
Company  Company1  
Division division1  
City     City1  
name     peter             // this should be in the first row as a second column  
Company  Company2          
Division division2  
City     City2
...

1 个答案:

答案 0 :(得分:1)

这非常难看,但这是我能够找到如何在SQL Server中完成所需工作的唯一方法。如果您复制并粘贴代码,它应该运行并为您提供结果并保持数据库清洁。我使用一些永久表来解决一些动态的sql作用域限制,但是在它完成之前我都放弃它们。

If      Object_ID('tempdb..#userInfo') Is Not Null Drop Table #userInfo
Create  Table #userInfo (id Int, name Varchar(100), company Varchar(100), division Varchar(100), city Varchar(100))

Insert  #userInfo (id, name, company, division, city)
Values  (1, 'john','company1', 'division1', 'city1'),
        (2, 'peter','company2', 'division2', 'city2'),
        (3, 'mary','company3', 'division3', 'city3'),
        (4, 'timmy','company4', 'division4', 'city4'),
        (5, 'nancy','company5', 'division5', 'city5'),
        (6, 'james','company6', 'division6', 'city6'),
        (7, 'brandon','company7', 'division7', 'city7'),
        (8, 'jay','company8', 'division8', 'city8')

If      Object_ID('tempdb..#unPivoted') Is Not Null Drop Table #unPivoted
Create  Table #unPivoted (id Int, rid Int, col Varchar(100), value Varchar(100))

Insert  #unPivoted
Select  id, Row_Number() Over (Partition By id Order By value) As rID, col, value
From    #userInfo p
Unpivot (value For col In (name, company, division, city)) As u

If      Object_ID('dbo.TempQueryOutput') Is Not Null Drop Table dbo.TempQueryOutput

Select  1 As OrderCol,'City' As ColName Into dbo.TempQueryOutput
Union
Select  2,'Company'
Union
Select  3,'Division'
Union
Select  4,'Name'


Declare @sql Nvarchar(Max),
        @maxID Int,
        @loopIter Int = 1

Select  @maxID = Max(id)
From    #userInfo

While   @loopIter <= @maxID
Begin
        Set     @sql = 'Select  o.*, u.value As Col' + Convert(Nvarchar(100),@loopIter) + ' Into dbo.TempQueryTable
                        From    dbo.TempQueryOutput o
                        Join    #unPivoted u
                                On  o.OrderCol = u.rid
                                And u.id = ' + Convert(Nvarchar(100),@loopIter)

        Exec    sp_executeSQL @sql

        If      Object_ID('dbo.TempQueryOutput') Is Not Null Drop Table dbo.TempQueryOutput

        Select  * Into dbo.TempQueryOutput
        From    dbo.TempQueryTable

        If      Object_ID('dbo.TempQueryTable') Is Not Null Drop Table dbo.TempQueryTable

        Set     @loopIter = @loopIter + 1

End

Update  dbo.TempQueryOutput
Set     OrderCol =  Case 
                    When ColName = 'Name' Then 1
                    When ColName = 'Company' Then 2
                    When ColName = 'Division' Then 3
                    When ColName = 'City' Then 4
                    End

Select  *
From    dbo.TempQueryOutput
Order   By OrderCol             

If      Object_ID('dbo.TempQueryOutput') Is Not Null Drop Table dbo.TempQueryOutput