SQL Server making rows into columns

后端 未结 1 1484
温柔的废话
温柔的废话 2021-01-16 01:22

I\'m trying to take three tables that I have and show the data in a way the user asked me to do it. The tables look like this. (I should add that I am using MS SQL Server)

1条回答
  •  不思量自难忘°
    2021-01-16 02:00

    There are several ways that you can get the result, including using the PIVOT function.

    You can use an aggregate function with a CASE expression:

    select t1.aid, t1.status, t1.[group],
      max(case when t2.traitname = 'trait1' then t3.trait end) trait1,
      max(case when t2.traitname = 'trait2' then t3.trait end) trait2,
      max(case when t2.traitname = 'trait3' then t3.trait end) trait3
    from table1 t1
    inner join table3 t3
      on t1.aid = t3.aid
    inner join table2 t2
      on t3.atid = t2.atid
    group by t1.aid, t1.status, t1.[group];
    

    See SQL Fiddle with Demo

    The PIVOT function requires an aggregate function this is why you would need to use either the MIN or MAX function (since you have a string value).

    If you have a limited number of traitnames then you could hard-code the query:

    select aid, status, [group],
      trait1, trait2, trait3
    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
    ) d
    pivot
    (
      max(trait)
      for traitname in (trait1, trait2, trait3)
    ) piv;
    

    See SQL Fiddle with Demo.

    If you have an unknown number of values, then you will want to look at using dynamic SQL to get the final result:

    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;
    

    See SQL Fiddle with Demo

    0 讨论(0)
提交回复
热议问题