【问题标题】:How to convert row to column in my case using SQL Server? [duplicate]在我的情况下,如何使用 SQL Server 将行转换为列? [复制]
【发布时间】:2020-02-24 19:54:37
【问题描述】:

我需要将一行转换为一列,我从未在这种情况下工作过。

产品

 ProdID   Price
 ---------------
 111      52.5
 111      50.5
 112      40
 111      65

预期结果:

ProdID    Price1    Price2    Price3
------------------------------------
111       52.5      50.5     65
112       40

注意

我不知道同一件商品会有多少价格。有时只有一个,有时是 2 或 5 个。

因此,它必须创建列。

我看到很多帖子只转换了确切的列,而不是像我的场景这样的动态列。

【问题讨论】:

  • 您需要一个类似于here 描述的动态 SQL 查询
  • @Nick 在我的例子中,列名是Price1, Price2, Price3。非静态列
  • 您可以与GROUP_CONCAT 亲密接触。例如:SELECT ProdID, Prices AS GROUP_CONCAT(Price, ',') FROM Product GROUP BY ProdID
  • @AjahnCharles 我搜索GROUP_CONCAT。我不想那样。您的结果将显示在单列中。但这是我了解Group_concat 的好消息,谢谢
  • @Liamneesan GROUP_CONCAT 是 MySQL,而不是 SQL Server。

标签: sql sql-server pivot


【解决方案1】:

Demo on db<>fiddle

  1. 你需要像https://stackoverflow.com/a/60331153一样使用Dynamic SQL PIVOT
  2. 使用ROW_NUMBER()结合CONCAT()来标记动态列,如Price1, Price2, Price3, etc.
    DECLARE 
        @columns NVARCHAR(MAX) = '',
        @sql     NVARCHAR(MAX) = '';


     SELECT ProdID, Price, Col = CONCAT('Price', ROW_NUMBER() OVER (PARTITION BY ProdID ORDER BY ProdID))
     into #b
     FROM #a

    SELECT @columns += QUOTENAME(Col) + ','
    from (SELECT DISTINCT Col FROM #b) A

    -- remove the last comma
    SET @columns = LEFT(@columns, LEN(@columns) - 1);


    SET @sql = 'SELECT * FROM ( SELECT ProdID, Price, Col FROM  #b) src PIVOT( MAX([Price]) FOR Col IN ('+ @columns +')) AS pivot_table;';

    -- execute the dynamic SQL
    EXECUTE sp_executesql @sql;

输出

【讨论】:

  • 你应该投票决定关闭一个基本相同的东西。
  • 我确实这么认为。但是PARTITION BY ProdID ORDER BY ProdID 有点不同。所以还是想给OP给出答案。
【解决方案2】:
    Create table ItemDetails
(
    prodid numeric(10),
    price numeric(10,2),
    orderno int identity(1,1)
)

declare @pricecols varchar(max)='',
@pricecolName nvarchar(max)='',
@statement nvarchar(4000)=''

 select @pricecolName= stuff( 
            (
                select ','+pricecol from (
             select  distinct 'price'+convert(varchar(10),(row_number() over(partition by prodid order by orderno))) 
            pricecol FROM ItemDetails   ) as tbl
            for xml path('')),1,1,'')


set @statement= 'select prodID,'+@pricecolName+' from (
    select  prodid,price,''price''+convert(varchar(10),(row_number() 
    over(partition by prodid order by orderno))) as
            pricecol FROM ItemDetails  
) [itemPrice]
pivot
(
    max(price)
    for pricecol
    in ('+@pricecolName+') ) as pivatetble'

 exec sp_executesql  @statement

OutPut- (note: price value duplicated for Item2 [112])1

【讨论】:

    猜你喜欢
    • 2021-02-02
    • 1970-01-01
    • 1970-01-01
    • 2021-08-21
    • 2018-02-19
    • 2018-09-05
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多