【问题标题】:How to convert rows from multiple tables into columns with values in SQL Server 2005如何在 SQL Server 2005 中将多个表中的行转换为具有值的列
【发布时间】:2012-03-19 20:52:37
【问题描述】:

我有一个用户表。

以及包含用户可以说的语言的第二语言表

和包含用户护照详细信息的第三个护照表(用户可以拥有多个护照)

[我还有 5 张桌子除了这些]

我想将这些语言和护照行转换为一个结果集(也包含用户详细信息),并且在结果集中它应该根据语言显示每个用户记录的语言和护照列的是/否值用户可以说话以及他们拥有什么护照。输出如下所示:

我们可以通过使用 PIVOT 来做到这一点。我尝试使用单个表,但如何为多个表执行此操作。

谢谢

【问题讨论】:

    标签: sql-server-2005 tsql pivot


    【解决方案1】:

    可能是这样的:

    首先是测试数据:

    CREATE TABLE #tblUser 
                (
                    userid INT, 
                    userName VARCHAR(100),
                    department VARCHAR(100)
                )
    CREATE TABLE #tblLanguage 
                (
                    uniqueid INT,
                    userid INT,
                    [language] VARCHAR(100)
                )
    CREATE TABLE #tblContryPassport
                (
                    uniqueid INT,
                    userid INT,
                    contryPassport VARCHAR(100)
                )
    INSERT INTO #tblUser
    VALUES
        (1,'aa','TT'),
        (2,'bb','gg'),
        (3,'cc','rr'),
        (4,'dd','dd')
    INSERT INTO #tblLanguage
    VALUES
        (1,1,'American'),
        (1,1,'Arabic'),
        (1,2,'Azerbaujani'),
        (1,3,'Bulgarian'),
        (1,3,'Chaochow'),
        (1,4,'Behdini')
    INSERT INTO #tblContryPassport
    VALUES
        (1,1,'Hongkong'),
        (1,1,'Malaysia'),
        (1,2,'Spain'),
        (1,3,'China'),
        (1,4,'India'),
        (1,4,'UK')
    

    然后连接枢轴的唯一列。如果有两个,则选择其中之一:

    DECLARE @cols VARCHAR(MAX),
            @colsWithIsNull VARCHAR(MAX)
    ;WITH CTE
    AS
    (
        SELECT
            #tblContryPassport.contryPassport AS Name
        FROM
            #tblContryPassport
        UNION ALL
        SELECT
            #tblLanguage.[language] AS Name
        FROM
            #tblLanguage
    ), CTE2
    AS
    (
        SELECT
            ROW_Number() OVER(PARTITION BY name ORDER BY name) AS iRank,
            CTE.Name
        FROM
            CTE
    )
    SELECT  @cols = COALESCE(@cols + ','+QUOTENAME(Name),
                         QUOTENAME(Name)),
            @colsWithIsNull=COALESCE(@colsWithIsNull + ',ISNULL('+QUOTENAME(Name)+',''no'') AS '+QUOTENAME(Name),
                         'ISNULL('+QUOTENAME(Name)+',''no'') AS '+QUOTENAME(Name))
    FROM
        CTE2
    WHERE
        iRank=1
    

    然后像这样做一个动态枢轴:

    DECLARE @query NVARCHAR(4000)=
    N';WITH CTE
    AS
    (
        SELECT
            #tblContryPassport.userid,
            ''yes'' AS Answer,
            #tblContryPassport.contryPassport AS Name
        FROM
            #tblContryPassport
        UNION ALL
        SELECT
            #tblLanguage.userid,
            ''yes'' AS Answer,
            #tblLanguage.[language] AS Name
        FROM
            #tblLanguage
    )
    SELECT
        userName,
        department,
        '+@colsWithIsNull+'
    FROM
    (
        SELECT
            #tblUser.userid,
            #tblUser.userName,
            #tblUser.department,
            CTE.Answer,
            CTE.Name
        FROM
            #tblUser
            JOIN CTE
                ON #tblUser.userid=CTE.userid
    ) AS p
    PIVOT
    (
        MAX(Answer)
        FOR Name IN ('+@cols+')
    ) AS pvt'
    
    EXECUTE(@query)
    

    然后在我的情况下,我将删除临时表:

    DROP TABLE #tblUser
    DROP TABLE #tblContryPassport
    DROP TABLE #tblLanguage
    

    【讨论】:

    • 很高兴为您提供帮助.. 编码愉快:P
    • @Arion:我再次需要你的帮助。请查看标签后面的更新问题“与其他表格一起移动”
    • 是的,我认为这将很难获得该输出,因为正如您所说,您没有任何关系。您所做的编辑是一个新问题,所以如果您想要新的答案。问一个新问题。
    • 我提出了新问题并将其从该问题中删除。请记住当前情况,因为我需要在回答新问题时将该解决方案合并到该解决方案中。新问题的 URL 是 stackoverflow.com/questions/9531771/…。谢谢
    【解决方案2】:

    你可以试试

    select
      *
    from
    (
      select
        u.Username, u.department, c.countrypassport
      from User U
      inner join country C
        on C.userid=U.userid
    ) DataTable
    PIVOT
    (
      SUM(countrypassport)
      FOR countrypassport
      IN (
        [American],[Arabic],.....
      )
    ) PivotTable
    

    【讨论】:

      猜你喜欢
      • 2012-03-20
      • 2012-08-04
      • 1970-01-01
      • 2013-05-20
      • 2012-03-19
      • 2021-12-21
      • 2018-05-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多