Sql 基于某些ID将表的行显示为列

Sql 基于某些ID将表的行显示为列,sql,sql-server,tsql,pivot,Sql,Sql Server,Tsql,Pivot,我有一张像这样的桌子 ID option 1 optionA 1 optionB 1 optionC 1 optionD 我想要的结果是: ID A B C D 1 optionA optionB optionC optionD 最好的方法是什么 我尝试过的问题是 select * from TableName PIVOT (option for ID = 2674 )) as abc

我有一张像这样的桌子

 ID     option
 1      optionA
 1      optionB
 1      optionC
 1      optionD
我想要的结果是:

ID    A        B       C       D
1  optionA  optionB optionC optionD
最好的方法是什么

我尝试过的问题是

select * from TableName PIVOT (option for ID = 2674 )) as abc 
这将不起作用,因为PIVOT需要聚合函数

我也尝试过这样的合并

declare @t table(num VARCHAR(100))
insert into @t 
    select choice FROM QuestionAnswers where QuestionID=2674
select num from @t
declare @s varchar(8000)
select  @s = COALESCE(@s + ',', '') + num
from    @t
exec('select '+@s)
但这也不管用

CREATE TABLE Product(Cust VARCHAR(25), Product VARCHAR(20), QTY INT)
GO
-- Inserting Data into Table
INSERT INTO Product(Cust, Product, QTY)
VALUES('KATE','VEG',2)
INSERT INTO Product(Cust, Product, QTY)
VALUES('KATE','SODA',6)
INSERT INTO Product(Cust, Product, QTY)
VALUES('KATE','MILK',1)
INSERT INTO Product(Cust, Product, QTY)
VALUES('KATE','BEER',12)
INSERT INTO Product(Cust, Product, QTY)
VALUES('FRED','MILK',3)
INSERT INTO Product(Cust, Product, QTY)
VALUES('FRED','BEER',24)
INSERT INTO Product(Cust, Product, QTY)
VALUES('KATE','VEG',3)
GO
-- Selecting and checking entires in table
SELECT *
FROM Product
GO
-- Pivot Table ordered by PRODUCT
SELECT PRODUCT, FRED, KATE
FROM (
SELECT CUST, PRODUCT, QTY
FROM Product) up
PIVOT (SUM(QTY) FOR CUST IN (FRED, KATE)) AS pvt
ORDER BY PRODUCT
GO
-- Pivot Table ordered by CUST
SELECT CUST, VEG, SODA, MILK, BEER, CHIPS
FROM (
SELECT CUST, PRODUCT, QTY
FROM Product) up
PIVOT (SUM(QTY) FOR PRODUCT IN (VEG, SODA, MILK, BEER, CHIPS)) AS pvt
ORDER BY CUST
GO
-- Unpivot Table ordered by CUST
SELECT CUST, PRODUCT, QTY
FROM
(
SELECT CUST, VEG, SODA, MILK, BEER, CHIPS
FROM (
SELECT CUST, PRODUCT, QTY
FROM Product) up
PIVOT
( SUM(QTY) FOR PRODUCT IN (VEG, SODA, MILK, BEER, CHIPS)) AS pvt) p
UNPIVOT
(QTY FOR PRODUCT IN (VEG, SODA, MILK, BEER, CHIPS)
) AS Unpvt
GO
-- Clean up database
DROP TABLE Product
GO
参考号

编辑

参考号

编辑


这种类型的数据转换称为枢轴。在SQL Server 2005+中,有一个函数将为您执行此数据轮换。但是,有许多方法可以执行此数据转换

以下是一个PIVOT查询,可用于您的示例数据:

select *
from
(
  select id, [option], right([option], 1) col
  from yourtable
) src
pivot
(
  max([option])
  for col in (a, b, c, d)
) piv

这也可以通过使用带有CASE表达式的聚合函数来执行:

select id,
  max(case when col = 'a' then [option] else null end) a,
  max(case when col = 'b' then [option] else null end) b,
  max(case when col = 'c' then [option] else null end) c,
  max(case when col = 'd' then [option] else null end) d
from
(
  select  id, [option], right([option], 1) col
  from yourtable
) src
group by id

您可以在表上执行多个联接:

select a.id,
  a.[option] a,
  b.[option] b,
  c.[option] c,
  d.[option] d
from yourtable a
left join yourtable b
  on a.id = b.id
  and right(b.[option], 1) = 'b'
left join yourtable c
  on a.id = c.id
  and right(c.[option], 1) = 'c'
left join yourtable d
  on a.id = d.id
  and right(d.[option], 1) = 'd'
where right(a.[option], 1) = 'a'

最后,如果要转换为列的值未知,则可以使用动态sql执行此操作:

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

select @colsName = STUFF((SELECT distinct ', ' + QUOTENAME(right([option], 1)) +' as '+ right([option], 1)
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @cols = STUFF((SELECT distinct ', ' + QUOTENAME(right([option], 1))
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'SELECT id, ' + @colsName + ' from 
             (
                select id, [option], right([option], 1) col
                from yourtable
            ) x
            pivot 
            (
                max([option])
                for col in (' + @cols + ')
            ) p '

execute(@query)

所有查询的结果为:

| ID |       A |       B |       C |       D |
----------------------------------------------
|  1 | optionA | optionB | optionC | optionD |

这种类型的数据转换称为枢轴。在SQL Server 2005+中,有一个函数将为您执行此数据轮换。但是,有许多方法可以执行此数据转换

以下是一个PIVOT查询,可用于您的示例数据:

select *
from
(
  select id, [option], right([option], 1) col
  from yourtable
) src
pivot
(
  max([option])
  for col in (a, b, c, d)
) piv

这也可以通过使用带有CASE表达式的聚合函数来执行:

select id,
  max(case when col = 'a' then [option] else null end) a,
  max(case when col = 'b' then [option] else null end) b,
  max(case when col = 'c' then [option] else null end) c,
  max(case when col = 'd' then [option] else null end) d
from
(
  select  id, [option], right([option], 1) col
  from yourtable
) src
group by id

您可以在表上执行多个联接:

select a.id,
  a.[option] a,
  b.[option] b,
  c.[option] c,
  d.[option] d
from yourtable a
left join yourtable b
  on a.id = b.id
  and right(b.[option], 1) = 'b'
left join yourtable c
  on a.id = c.id
  and right(c.[option], 1) = 'c'
left join yourtable d
  on a.id = d.id
  and right(d.[option], 1) = 'd'
where right(a.[option], 1) = 'a'

最后,如果要转换为列的值未知,则可以使用动态sql执行此操作:

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

select @colsName = STUFF((SELECT distinct ', ' + QUOTENAME(right([option], 1)) +' as '+ right([option], 1)
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @cols = STUFF((SELECT distinct ', ' + QUOTENAME(right([option], 1))
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'SELECT id, ' + @colsName + ' from 
             (
                select id, [option], right([option], 1) col
                from yourtable
            ) x
            pivot 
            (
                max([option])
                for col in (' + @cols + ')
            ) p '

execute(@query)

所有查询的结果为:

| ID |       A |       B |       C |       D |
----------------------------------------------
|  1 | optionA | optionB | optionC | optionD |

你试过什么?发布一些工作查询,不管结果是否不正确,这是一个起点,也许你离解决方案不远。@rahul你试过我的ans吗?我试过像这样的透视选择*从问题答案透视选择问题ID=2674作为abc;但这不起作用,因为PIVOT需要一些聚合函数…@vikas您的答案不太可能适用于他,除非他的数据库与您的示例数据库完全相同。@Rahul,编辑您的问题,并将您尝试过的查询以及结果或错误(如果有错误)发布在那里。这样,其他人就不需要阅读所有评论来寻求对问题的更正或修改。你尝试过什么?发布一些工作查询,不管结果是否不正确,这是一个起点,也许你离解决方案不远。@rahul你试过我的ans吗?我试过像这样的透视选择*从问题答案透视选择问题ID=2674作为abc;但这不起作用,因为PIVOT需要一些聚合函数…@vikas您的答案不太可能适用于他,除非他的数据库与您的示例数据库完全相同。@Rahul,编辑您的问题,并将您尝试过的查询以及结果或错误(如果有错误)发布在那里。这样,其他人就不需要阅读所有注释来寻求对问题的更正或修改。从SELECT id中选择*,[选项],从右[选项],从表格中选择1列src pivot max[选项]对于a、b、c、d piv中的列,这将不起作用,因为我的数据可以是任何内容,而不仅仅是选项a,optionB等…@Rahul那么你应该看看我在答案中包含的最终版本,动态one@Rahul谢谢你给了我一个一般性的指导方针,作为一个好奇的程序员,我可以自己学习和探索,以提高自己???选择*从选择id,[option],右[option],表中的1列src pivot max[选项]用于a、b、c、d piv中的列这将不起作用,因为我的数据可以是任何东西,而不仅仅是optionA、optionB等…@Rahul那么你应该看看我在回答中包含的最终版本,动态one@Rahul谢谢你给了我一个一般性的指导方针,作为一个好奇的程序员,我可以自己学习和探索,以提高自己???