将列变成分区的行

时间:2018-07-05 18:55:47

标签: sql sql-server tsql pivot

我有一张这样的桌子:

CFL52_ID     CFL52_PRICE    CFL51_MILEAGE
------------ --------------- -----------------
1            100000.00       10000
1            200000.00       20000
2            800000.00       10000
2            900000.00       20000

我想将列透视成行。 Mileage是列标题,而Price是列值。变成这样的东西:

CFL52_ID     [10000]         [20000]
------------ --------------- -----------------
1            100000.00       200000.00
2            800000.00       900000.00

请注意,id正在分组,价格被调整,并且里程变成列标题,里程是动态的-可以增加-。

我尝试了以下失败:

   SELECT  [10000],[20000]   
    FROM  (     SELECT 
                    CFL52_PRICE as indicatorvalue,          
                    CFL51_MILEAGE as indicatorname        
                FROM [TFL52_PRICES_M] p          
                    INNER JOIN [TFL51_PARAM_MILEAGE] k ON CFL52_CFL51_CODIGO = CFL51_CODIGO       
                WHERE CFL52_DATES = '2018-07-01 00:00:00.000' AND CFL52_DATEEN= '2018-07-02 00:00:00.000') as a   
    pivot 
    (
        max(indicatorvalue) for indicatorname in ([10000],[20000]) 
    ) p

2 个答案:

答案 0 :(得分:2)

只需使用条件聚合即可。您还应该使用别名来指示列所属的表。

select CFL52_ID
    , [10000] = MAX(case when CFL51_MILEAGE = 10000 then CFL52_PRICE end)
    , [20000] = MAX(case when CFL51_MILEAGE = 20000 then CFL52_PRICE end)
FROM [TFL52_PRICES_M] p          
INNER JOIN [TFL51_PARAM_MILEAGE] k ON CFL52_CFL51_CODIGO = CFL51_CODIGO       
WHERE CFL52_DATES = '2018-07-01 00:00:00.000' 
    AND CFL52_DATEEN= '2018-07-02 00:00:00.000'
group by CFL52_ID

答案 1 :(得分:1)

要管理动态标题,您需要动态TSQL:

if OBJECT_ID('dbo.test') is null 
create table dbo.test(CFL52_ID varchar(50), CFL52_PRICE decimal(18,2), CFL51_MILEAGE int) 
--populate test table
insert into dbo.test values 
(1, 100000.00, 10000), 
(1, 200000.00, 20000), 
(2, 800000.00, 10000), 
(2, 900000.00, 20000)

declare @columns nvarchar(max)='' --holds all the numbers that will become column names 
declare @sql nvarchar(max)='' --contains the TSQL dinamically generated 

--generate dynamic column names
select @columns = @columns + ', [' + cast(CFL51_MILEAGE as varchar(max))+ ']' 
from dbo.test 
group by CFL51_MILEAGE 

--remove first (unnecessary) comma
set @columns = RIGHT(@columns, len(@columns)-2) 

--build dynamic TSQL query
set @sql = @sql + ' select piv.[CFL52_ID], ' + @columns 
set @sql = @sql + ' from ( ' 
set @sql = @sql + ' select [CFL52_ID], [CFL52_PRICE], [CFL51_MILEAGE] ' 
set @sql = @sql + ' from dbo.test ' 
set @sql = @sql + ' ) src ' 
set @sql = @sql + ' pivot ( ' 
set @sql = @sql + ' max([CFL52_PRICE]) ' 
set @sql = @sql + ' for [CFL51_MILEAGE] in ('+@columns+') ' 
set @sql = @sql + ' ) piv ' 

--execute  dynamic TSQL query
exec(@sql)

输出:

enter image description here

如果将CFL51_MILEAGE值分别为10000和20000的行添加到输入表中,则输入和输出表将为:

enter image description here

如果您在输入表中添加更多行以引入新的CFL51_MILEAGE值(而不是10000或20000),则输入和输出表将为:

enter image description here