【问题标题】:How can I dynamically convert row to columns and have different column name for each column如何动态地将行转换为列并为每列设置不同的列名
【发布时间】:2019-03-30 10:27:06
【问题描述】:

如何将行转换为列并为每列创建不同的名称?

create table #TempTable  (InvoiceNum int,State varchar(2), ChargeName varchar(50),  PercentageRate decimal(5,3), FlatRate decimal(5,2))
insert into #TempTable values   (235736, 'AZ','Inspection & Policy Fee',  NULL,250.00)
                                ,(235736, 'AZ','Surplus Line Tax',0.03,NULL)
                                ,(235736, 'AZ','Stamping Fee',0.002,NULL

)

我需要这样的东西:

更新:

使用示例我能够对其进行反透视,但结果不是我想要的:

create table #TempTable  (InvoiceNum int,State varchar(2), ChargeName varchar(50),  PercentageRate decimal(5,3), FlatRate decimal(5,2))
insert into #TempTable values   (235736, 'AZ','Inspection & Policy Fee',  NULL,250.00)
                                ,(235736, 'AZ','Surplus Line Tax',0.03,NULL)
                                ,(235736, 'AZ','Stamping Fee',0.002,NULL)

--select * from @TempTable


Declare @SQL nvarchar(max),
        @query nvarchar(max)

select @SQL = STUFF((SELECT ',' + QUOTENAME(ChargeName) 
                    from #TempTable
                    group by ChargeName, InvoiceNum
                    order by InvoiceNum
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')
--select @SQL
set   @SQL = 'SELECT ' + @SQL + '  from
        (
            select PercentageRate, ChargeName
            from #TempTable
        ) x
        pivot
        (
        max(PercentageRate)
        for ChargeName in (' + @SQL + ')
        ) p '

exec sp_executesql @SQL;

更新:

运行下面的查询给了我这个:

为什么 ChargeName 不在第一行?我希望看到它是这样的:我错过了什么?

declare  @TempTable table  (InvoiceNum int,StateID varchar(2), ChargeName varchar(50),  PercentageRate decimal(5,3), FlatRate decimal(5,2))
insert into @TempTable values   (235736, 'AZ','Inspection & Policy Fee',  NULL,250.00)
                                ,(235736, 'AZ','Surplus Line Tax',0.03,NULL)
                                ,(235736, 'AZ','Stamping Fee',0.002,NULL)
select 
        InvoiceNum,
        ChargeName,
        StateID,
        PercentageRate,
        FlatRate,
        row_number() over (partition by InvoiceNum order by ChargeName) as RN
into #TempTable
 from @TempTable #TempTable

DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE @ColumnName AS NVARCHAR(MAX)

--Get distinct values of the PIVOT Column 
SELECT @ColumnName= ISNULL(@ColumnName + ',','') 
       + QUOTENAME(RN)
FROM (SELECT DISTINCT RN FROM #TempTable) AS RN

--Prepare the PIVOT query using the dynamic 
SET @DynamicPivotQuery = 
  N'SELECT InvoiceNum,  ' + @ColumnName + '
    FROM #TempTable
    PIVOT(MAX(ChargeName) 
          FOR RN IN (' + @ColumnName + ')) AS PVTTable'

EXEC sp_executesql @DynamicPivotQuery
drop table #TempTable

【问题讨论】:

  • 如果您仍然认为这不是重复的,请尝试使用 row_number 为 Tax1、Tax2.. 添加一个计算列,然后使用上面的链接来实现您正在寻找的结果。
  • 谢谢。我用那个例子来达到某个目的。但是很困惑如何修改它以获得理想的结果。我更新了问题。再次感谢
  • 这将需要多个枢轴并且变得非常丑陋。我展示了如何做动态列here,但我认为它需要你做 3 次

标签: sql-server tsql pivot dynamic-sql


【解决方案1】:

我会根据需要多次加入临时表。 鉴于您的#TempTable

SELECT T1.InvoiceNum,
    Tax1_Jurisdiction = T1.State, Tax1_TaxType = T1.ChargeName, Tax1_Percent = T1.PercentageRate, Tax1_FixedRate = T1.FlatRate, 
    Tax2_Jurisdiction = T2.State, Tax2_TaxType = T2.ChargeName, Tax2_Percent = T2.PercentageRate, Tax2_FixedRate = T2.FlatRate, 
    Tax3_Jurisdiction = T3.State, Tax3_TaxType = T3.ChargeName, Tax3_Percent = T3.PercentageRate, Tax3_FixedRate = T3.FlatRate
FROM #TempTable T1
JOIN #TempTable T2 ON T1.InvoiceNum = T2.InvoiceNum
JOIN #TempTable T3 ON T1.InvoiceNum = T3.InvoiceNum
WHERE T1.ChargeName = 'Inspection & Policy Fee'
    AND T2.ChargeName = 'Surplus Line Tax'
    AND T3.ChargeName = 'Stamping Fee'
;

【讨论】:

  • 收费次数也是动态的吗?如果不是,那么您可以使用变量或另一个临时表来指定不同的收费代码以及它们应该应用的顺序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多