Sql pivot - but dont sum the values

前端 未结 1 1295
甜味超标
甜味超标 2021-01-28 11:56

I have a table schema that looks like this

CREATE TABLE [dbo].[Discounts](
      [Id] [int] NOT NULL,
      [ProductId] [varchar(50)] NOT NULL,
      [LowerBound         


        
1条回答
  •  -上瘾入骨i
    2021-01-28 12:02

    Since you are using SQL Server, there are several ways that you can convert the rows of data into columns.

    You can use an aggregate function with a CASE expression to get the result:

    select productid,
      max(case when lower = 0 and upper = 10 then discount end) [0-10],
      max(case when lower = 10 and upper = 30 then discount end) [10-30],
      max(case when lower = 30 and upper = 60 then discount end) [30-60],
      max(case when lower = 60 and upper = 90 then discount end) [60-90],
      max(case when lower = 90 and upper = 120 then discount end) [90-120]
    from CorporateSpread
    group by productid;
    

    See SQL Fiddle with Demo.

    If you are using SQL Server 2005+, then you can use the PIVOT function:

    select productid, [0-10], [10-30], [30-60], [60-90],[90-120]
    from 
    (
      select productid,
        discount,
        cast(lower as varchar(10)) + '-' + cast(upper as varchar(10)) rng
      from CorporateSpread
    ) d
    pivot
    (
      max(discount)
      for rng in ([0-10], [10-30], [30-60], [60-90],[90-120])
    ) piv;
    

    See SQL Fiddle with Demo.

    The above two version work great if you have a known number of values, but if you have an unknown number of ranges, then you will need to to use dynamic SQL:

    DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)
    
    select @cols = STUFF((SELECT distinct ',' + QUOTENAME(cast(lower as varchar(10)) + '-' + cast(upper as varchar(10))) 
                        from CorporateSpread
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
    set @query = 'SELECT productid, ' + @cols + ' 
                from 
                (
                    select productid,
                      discount,
                      cast(lower as varchar(10)) + ''-'' + cast(upper as varchar(10)) rng
                    from CorporateSpread
                ) x
                pivot 
                (
                    max(discount)
                    for rng in (' + @cols + ')
                ) p '
    
    execute sp_executesql @query;
    

    See SQL Fiddle with Demo. All versions will give a result:

    | PRODUCTID | 0-10 | 10-30 | 30-60 | 60-90 | 90-120 |
    -----------------------------------------------------
    |  product1 |    0 |     1 |     2 |     3 |      4 |
    |  product2 |    0 |     1 |     2 |     3 |      4 |
    

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