SQL Server:多列的动态数据透视

Posted

技术标签:

【中文标题】SQL Server:多列的动态数据透视【英文标题】:SQL Server : dynamic pivot over many columns 【发布时间】:2022-01-06 08:37:13 【问题描述】:

我有一张如下所示的表格:

DECLARE @Temp TABLE (
 fldID bigint
,fldYear bigint
,fldMonth bigint
,fldMonthName nvarchar(350)
,fldPayrollId bigint
,fldFullName nvarchar(350)
,fldDailyWage float
,fldMonthlyWage  float
,fldkarkardDay  float
,fldPriceMaskan  float
,fldPriceChild float
,fldPriceFood  float
,fldAllAdditions  float
,fldPriceTax  float
,fldPriceSanavat  float
,fldPriceEzafeKari  float
,fldPriceEidiPadash  float
,fldEmployeeShare  float
,fldEmployerShare  float
,fldUnemploymentShare  float
,fldSumEmployer  float);

像这样

insert @Temp(fldID, fldYear, fldMonth, fldMonthName, fldPayrollId, fldFullName, fldDailyWage, fldMonthlyWage , fldkarkardDay , fldPriceMaskan , fldPriceChild, fldPriceFood , fldAllAdditions , fldPriceTax , 
fldPriceSanavat, fldPriceEzafeKari , fldPriceEidiPadash , fldEmployeeShare , fldEmployerShare , fldUnemploymentShare , fldSumEmployer  )
values(1, 1400, 2, N'February', 212, N'500000', N'6500', N'29', N'52000', N'98750', N'1900000', N'900000', N'30000', N'900000', N'60000', N'650000', N'0', N'0', N'1900000', N'256000', N'256000'),(2, 1399, 3, N'March'   , 214, N'5200000', N'0', N'30', N'65900', N'6520', N'1900000', N'1000', N'98500', N'1900000', N'1900000', N'1900000', N'0', N'1900000', N'0', N'256000', N'0'),(3, 1400, 4, N'April'   , 216, N'62200000', N'35600', N'30', N'87900', N'65000', N'0', N'6520', N'1900000', N'1900000', N'0', N'1900000', N'1900000', N'1900000', N'1900000', N'256000', N'25600'),(4, 1399, 5, N'May'       , 218, N'522000', N'85000', N'2800', N'65400', N'52200', N'0', N'14780', N'1900000', N'1900000', N'0', N'1900000', N'0', N'1900000', N'1900000', N'256000', N'0')

我正在尝试如下所示的支点:

我的代码如下,但是pivot命令无法识别代码和正确的输出

SELECT 
     N'parameter' parameter
    ,p.fldMonthName 
    ,p.fldCols
FROM 
(
    SELECT 
        N'[fldDailyWage],[fldMonthlyWage],[fldkarkardDay],[fldPriceMaskan],[fldPriceChild],[fldPriceFood],[fldAllAdditions],[fldPriceTax]' fldCols
        ,* 
    FROM @Temp where fldYear = 1399
) x
PIVOT  
(
    count(fldID)
    FOR fldMonthName IN (fldCols)
) p

【问题讨论】:

这是一个非枢轴,而不是一个枢轴。 旁注,将货币值存储在float 中是一个糟糕的想法。使用 Base 10 数字数据类型。除非您有意让支付200.20 税款的人将其税值存储为200.1999969482421875(这会导致各种舍入错误) 这是一个 UNPIVOT,然后是本月的 PIVOT。你真的必须在 TSQL 中这样做吗?显示的透视和反透视最好在前端完成。 【参考方案1】:

我会使用 unpivot 按列参数分组,如下所示:

Select u.parameter, Sum(Case When fldMonth=2 Then u.value End) As 'February',
                    Sum(Case When fldMonth=5 Then u.value End) As 'May'
From
(
select fldMonth, [fldDailyWage],[fldMonthlyWage],[fldkarkardDay],[fldPriceMaskan],[fldPriceChild],[fldPriceFood],[fldAllAdditions],[fldPriceTax]
from @Temp) t
unpivot
( 
  value
  for parameter in ([fldDailyWage],[fldMonthlyWage],[fldkarkardDay],[fldPriceMaskan],[fldPriceChild],[fldPriceFood],[fldAllAdditions],[fldPriceTax])
) u
Group by u.parameter

【讨论】:

以上是关于SQL Server:多列的动态数据透视的主要内容,如果未能解决你的问题,请参考以下文章

具有多列日期的 SQL Server 数据透视表

动态 SQL 使用多列交叉应用来反透视数据

透视多列sql server

基于 SQL Server 中的一列透视多列

SQL Server 数据库中的动态数据透视

MS SQL Server 中的动态数据透视