将行转换为列

时间:2015-09-29 19:11:40

标签: sql-server tsql

我的表格中包含 UserID CountryName

现在我希望以这种方式获得记录

[UserId]   [ContryName1] [ContryName2] [ContryName3]......... 

2 个答案:

答案 0 :(得分:2)

在这里小提琴:http://sqlfiddle.com/#!6/cd6f1/1

DECLARE @SQL AS NVARCHAR(MAX)
WITH CTE AS
(
SELECT USERID,COUNTRYNAME,ROW_NUMBER() OVER(PARTITION BY USERID ORDER BY COUNTRYNAME) AS RN
FROM CNTRIES
)

SELECT @SQL = 'WITH CTE1 AS
(
SELECT USERID,COUNTRYNAME,ROW_NUMBER() OVER(PARTITION BY USERID ORDER BY COUNTRYNAME) AS RN
FROM CNTRIES
)
SELECT * 
FROM 
(SELECT USERID,COUNTRYNAME,RN FROM CTE1)C
PIVOT (MAX(COUNTRYNAME) FOR RN IN (['+STUFF((SELECT '],['+CAST(RN AS VARCHAR(100)) 
                                             FROM CTE 
                                             GROUP BY RN  
                                             FOR XML PATH('')),1,3,'')+'])) AS PIVOTT'

答案 1 :(得分:0)

如果您的版本是SQL Server 2005或更高版本,PIVOT是您的最佳选择,但是您没有说明版本并且尝试使用没有自然聚合的PIVOT可能很难掌握。如果您的版本低于2005,则会遇到更大的问题。否则,您需要将表连接到自身以获得相同的结果。您可以使用排名功能使其更容易一些。这样的事情虽然效率低下,但会产生类似的结果。

    /*
    IF OBJECT_ID('Countries','U') IS NOT NULL
        DROP TABLE Countries

    CREATE TABLE Countries
    (
          UserID INT
        , CountryName VARCHAR(255)
    )

    INSERT Countries
    VALUES (1, 'India')
        , (1, 'UK')
        , (2, 'USA')
        , (2, 'India') 
        , (2, 'Canada')
    */


    SELECT DISTINCT x.UserID, x.CountryName Country1, y.CountryName Country2, z.CountryName Country3
    FROM Countries c
        LEFT JOIN
        (
            SELECT *, RANK() OVER(PARTITION BY UserID ORDER BY UserID, CountryName) AS UserRank
            FROM Countries
        )x ON x.UserID = c.UserID AND x.UserRank=1
        LEFT JOIN 
        (
            SELECT *, RANK() OVER(PARTITION BY UserID ORDER BY UserID, CountryName) AS UserRank
            FROM Countries
        )y ON y.UserID = c.UserID AND y.UserRank=2
        LEFT JOIN 
        (
            SELECT *, RANK() OVER(PARTITION BY UserID ORDER BY UserID, CountryName) AS UserRank
            FROM Countries
        )z ON z.UserID = c.UserID AND z.UserRank=3