且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

SQL Server 2008:多个联接的列到行?

更新时间:2021-10-24 22:48:13

您可以使用PIVOT函数来转换此数据:

You can use the PIVOT function to transform this data:

select products_id,
  products_model,
  Isnull([Leather Seats], 'N') [Leather Seats], 
  Isnull([Heated Seats], 'N') [Heated Seats],
  Isnull([Tapedeck], 'N') [Tapedeck], 
  Isnull([Heater], 'N') [Heater], 
  Isnull([Hybrid], 'N') [Hybrid], 
  Isnull([Sunroof], 'N') [Sunroof],
  Isnull([Cruise Control], 'N') [Cruise Control]
from
(
  select p.products_id,
    p.products_model,
    c.categories_name,
    'Y' flag
  from products p
  left join Products_Categories pc
    on p.products_id = pc.products_id
  left join Categories c
    on pc.categories_id = c.categories_id
) src
pivot
(
  max(flag)
  for categories_name in ([Leather Seats], [Heated Seats],
                          [Tapedeck], [Heater], 
                          [Hybrid], [Sunroof],
                          [Cruise Control])                        
) piv

请参见带演示的SQL提琴.

如果categories_name值未知或不固定,则可以使用动态sql:

If the categories_name values are unknown or not fixed, then you can use dynamic sql:

DECLARE @cols AS NVARCHAR(MAX),
    @colsNull AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(categories_name) 
                    from Categories
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsNull = STUFF((SELECT ',IsNull(' + QUOTENAME(categories_name)+', ''N'')'+' as '+QUOTENAME(categories_name) 
                    from Categories
                    group by categories_name, categories_id
                    order by categories_id
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT products_id,
                  products_model,' + @colsNull + ' from 
             (
                select p.products_id,
                  p.products_model,
                  c.categories_name,
                  ''Y'' flag
                from products p
                left join Products_Categories pc
                  on p.products_id = pc.products_id
                left join Categories c
                  on pc.categories_id = c.categories_id
            ) x
            pivot 
            (
                max(flag)
                for categories_name in (' + @cols + ')
            ) p '

execute(@query)

请参见带有演示的SQL提琴

这两个查询的结果是:

| PRODUCTS_ID | PRODUCTS_MODEL | LEATHER SEATS | HEATED SEATS | TAPEDECK | HEATER | HYBRID | SUNROOF | CRUISE CONTROL |
-----------------------------------------------------------------------------------------------------------------------
|         300 |     Ford Focus |             N |            N |        N |      Y |      N |       N |              Y |
|         100 |     Saturn Vue |             N |            N |        Y |      N |      N |       N |              N |
|         200 |   Toyota Prius |             Y |            N |        N |      Y |      Y |       N |              N |