如何在SQL Server中水平显示数据?

3

我该如何横向显示表格数据?

这是我的表格定义:

create table [User]
(
    Id int primary key identity(1,1),
    Name varchar(50),
    Gender varchar(10)
)

以下是我在 SQL Server 表中拥有的数据。

+====+=======+========+
| Id | Name  | Gender |
+====+=======+========+
| 1  | Fahad | Male   |
+----+-------+--------+
| 2  | Saad  | Male   |
+----+-------+--------+
| 3  | Asif  | Male   |
+====+=======+========+

我希望将其水平展示如下:

+========+=======+======+======+
| Id     | 1     | 2    | 3    |
+========+=======+======+======+
| Name   | Fahad | Saad | Asif |
+--------+-------+------+------+
| Gender | Male  | Male | Male |
+========+=======+======+======+

1
使用 PIVOT https://technet.microsoft.com/zh-cn/library/ms177410(v=sql.105).aspx - Akash Amin
你最终会得到很多列。你知道吗? - sqluser
4个回答

4

也许可以使用UNPIVOTPIVOT的组合?

(不过您的列需要是相同的类型才能使其正常工作,如果您表中的类型不同,可以在SELECT/CTE等语句中使用CAST进行转换)

CREATE table [User](
Id int primary key identity(1,1),
Name varchar(50),
Gender varchar(50)
)

SET IDENTITY_INSERT [User] ON

INSERT INTO [User](Id,Name,Gender) VALUES 
(1, 'Fahad','Male'),
(2,'Saad','Male'),
(3,'Asif','Male')

SELECT * FROM [User]
UNPIVOT ([Value] FOR Cols IN ([Name],[Gender])) Unp
PIVOT   (MAX([Value]) FOR Id IN ([1],[2],[3])) Piv


Cols    1      2      3
------  ------ ------ -------
Gender  Male   Male   Male
Name    Fahad  Saad   Asif

(2 row(s) affected)
CASE也可以用来实现相同的功能 - 在SO上有大量的例子。
编辑:优秀的例子在SQL中转置列和行的简单方法?(这可能是那个问题的副本)。

1

是的,看起来我们可能需要同时使用UNPIVOTPIVOT

请尝试以下操作,它可能会给您提供与您期望的完全相同的结果。请先更改您的设计。

Gender varchar(10) to Gender varchar(50)

尝试以下内容:
;WITH cte AS(
                SELECT *
                FROM   [User]
                       UNPIVOT([Value] FOR Cols IN ([Name], [Gender])) Unp
                       PIVOT(MAX([Value]) FOR Id IN ([1], [2], [3])) Piv
            )
SELECT Cols  AS Id,
       [1],
       [2],
       [3]
FROM   cte
ORDER BY
       Id       DESC

1
这是一个适用于任何表的存储过程。它假定表键在第一列。
IF OBJECT_ID(N'[Invert]','P') IS NOT NULL 
    DROP PROCEDURE [Invert]
GO
CREATE PROCEDURE dbo.[Invert] @tbl sysname, @top int=1000 AS
DECLARE @key sysname SELECT @key=COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME=@tbl AND ORDINAL_POSITION=1
DECLARE @sql nvarchar(max), @ids varchar(max)
SET @sql='SELECT TOP '+CAST(@top as varchar(9))+' @out=COALESCE(@out+'','','''')+QUOTENAME('
    +QUOTENAME(@key)+') FROM '+QUOTENAME(@tbl)+' ORDER BY '+QUOTENAME(@key)
EXECUTE sp_executesql @sql, N'@out varchar(max) OUTPUT', @out=@ids OUTPUT
SET @sql=NULL
SELECT @sql=COALESCE(@sql+' UNION ALL ','')+'SELECT '''+COLUMN_NAME+''' AS '+QUOTENAME(@key)
    + ',* FROM (SELECT TOP '+CAST(@top as varchar(9))+' '+QUOTENAME(@key)+' k,CAST('
    + QUOTENAME(COLUMN_NAME)+'as varchar(8000)) m FROM '+QUOTENAME(@tbl)
    +' ORDER BY '+QUOTENAME(@key)+') t PIVOT (MAX(m) FOR k IN ('+@ids+')) x'+CHAR(13)
    FROM INFORMATION_SCHEMA.COLUMNS c WHERE TABLE_NAME=@tbl AND c.ORDINAL_POSITION>1
    ORDER BY c.ORDINAL_POSITION
EXECUTE(@sql)
GO

存储过程使用PIVOT来转置每一列。UNPIVOT很好用,但只能在所有列具有相同类型(包括长度)的情况下使用。该过程生成一个动态SELECT语句,使用UNION ALL运算符将每个列的PIVOT组合起来(除了键)。关键值列表(@ids)也是动态生成的,因为PIVOT命令需要一个显式的列列表。
然后您可以像这样调用它:
EXEC Invert [User]

第二个可选参数是顶部子句(默认为1000)。以下是返回最多5行的示例:
EXEC Invert [User], 5

0
create table [User]
(
    Id int primary key identity(1,1),
    Name varchar(50),
    Gender varchar(50),sal varchar(50)
)SET IDENTITY_INSERT [User] ON

--给所有字段分配相同的数据类型和大小

    INSERT INTO [User](Id,Name,Gender,sal) VALUES 
    (1, 'Fahad','Male',10000),
    (2,'Saad','Male',20000),
    (3,'Asif','Male',30000)

SELECT * FROM [User]
UNPIVOT ([Val] FOR Cols IN (name,gender,sal)) Unp
PIVOT   (MAX([Val]) FOR Id IN ([1],[2],[3])) Piv


Cols    1      2      3
------  ------ ------ -------
Gender  Male   Male   Male
Name    Fahad  Saad   Asif
sal     10000  20000  30000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接