在 Azure DW(Synapse) 中使用 Max 进行透视
Pivot using Max in Azure DW(Synapse)
我在 azure sql dw 中遇到了一个关于 pivot 的奇怪问题。我在分期 table 中有 2 行,如下所示
Select Flag, Number,Value,Interest from stg.tableA where Number = 400799074
Flag Number Value Interest
Federal 0400799074 12540.8 0
Provincial 0400799074 248.97 -0.01
枢轴和填充我的目的地 table 的查询如下
SELECT
Number
,MAX(CASE WHEN Flag = 'Federal' THEN ISNULL(stg.[Value], 0) ELSE 0 END) AS [FederalValue]
,MAX(CASE WHEN Flag = 'Provincial' THEN ISNULL(stg.[Value], 0) ELSE 0 END) AS [ProvincialValue]
,MAX(CASE WHEN Flag = 'Federal' THEN ISNULL(stg.[Interest], 0) ELSE 0 END) AS [FederalInterest]
,MAX(CASE WHEN Flag = 'Provincial' THEN ISNULL(stg.[Interest], 0) ELSE 0 END) AS [ProvincialInterest]
FROM
[stg].[TableA] stg
where LoanNumber = 400799074
GROUP BY
stg.Number
我得到的输出是
Number FederalValue ProvincialValue FederalIntrest ProvincialInterest
400799074 12540.8 248.97 0 0
我遗漏了一些东西,因为我不明白为什么 ProvincialInterest 是 0 而不是 -0.01
stg table 中的数据类型是 float,目标 table 是 decimal(15,2)。
当我删除 else 条件时,我得到了正确的结果,但我无法删除它们,因为在某些情况下,“provincial”行将不存在。
,MAX(CASE WHEN Flag = 'Provincial' THEN ISNULL(stg.[Interest], 0) /*ELSE 0 removed */ END) AS [ProvincialInterest]
快速示例数据
declare @tableA table
(
Flag nvarchar(20),
Number nvarchar(20),
Value money,
Interest money
);
insert into @tableA (Flag, Number, Value, Interest) values
('Federal', '0400799074', 12540.80, 0.0),
('Provincial', '0400799074', 248.97, -0.01),
('Federal', '0423456789', 123.45, 10.0); --Number without Provincial level
快速而肮脏的解决方案
在包含负值的数据集上获取最大值时,不应将未知 (null
) 值替换为 0(ISNULL(..., 0)
部分)。相反,您应该使用该数据类型的最小值。这里我只是用-99999
来证明'large negative value'点。
select Number
,MAX(CASE WHEN Flag = 'Federal' THEN ISNULL(stg.[Value], 0) ELSE -99999 END) AS [FederalValue]
,MAX(CASE WHEN Flag = 'Provincial' THEN ISNULL(stg.[Value], 0) ELSE -99999 END) AS [ProvincialValue]
,MAX(CASE WHEN Flag = 'Federal' THEN ISNULL(stg.[Interest], 0) ELSE -99999 END) AS [FederalInterest]
,MAX(CASE WHEN Flag = 'Provincial' THEN ISNULL(stg.[Interest], 0) ELSE -99999 END) AS [ProvincialInterest]
FROM @tableA stg
group by stg.Number;
此查询的结果具有所需 -0.01
,但还包含替换值 -99999.00
,仍必须对其进行处理才能获得请求的结果。
更好的解决方案
如果您不知道数据值的全部范围,则可能很难确定合适的负替换值(例如 -99999
)。因此我建议让 MAX()
函数处理未知数 (NULL
)。提示:该函数会忽略它们...最后一步替换任何 NULL
值。这意味着将 ISNULL()
函数移到 MAX()
函数之外。
select Number
,ISNULL(MAX(CASE WHEN Flag = 'Federal' THEN stg.[Value] END), 0) AS [FederalValue]
,ISNULL(MAX(CASE WHEN Flag = 'Provincial' THEN stg.[Value] END), 0) AS [ProvincialValue]
,ISNULL(MAX(CASE WHEN Flag = 'Federal' THEN stg.[Interest] END), 0) AS [FederalInterest]
,ISNULL(MAX(CASE WHEN Flag = 'Provincial' THEN stg.[Interest] END), 0) AS [ProvincialInterest]
from @tableA stg
group by stg.Number;
样本结果
更好 解决方案的结果。
Number FederalValue ProvincialValue FederalInterest ProvincialInterest
-------------------- --------------------- --------------------- --------------------- ---------------------
0400799074 12540,80 248,97 0,00 -0,01
0423456789 123,45 0,00 10,00 0,00
我在 azure sql dw 中遇到了一个关于 pivot 的奇怪问题。我在分期 table 中有 2 行,如下所示
Select Flag, Number,Value,Interest from stg.tableA where Number = 400799074
Flag Number Value Interest
Federal 0400799074 12540.8 0
Provincial 0400799074 248.97 -0.01
枢轴和填充我的目的地 table 的查询如下
SELECT
Number
,MAX(CASE WHEN Flag = 'Federal' THEN ISNULL(stg.[Value], 0) ELSE 0 END) AS [FederalValue]
,MAX(CASE WHEN Flag = 'Provincial' THEN ISNULL(stg.[Value], 0) ELSE 0 END) AS [ProvincialValue]
,MAX(CASE WHEN Flag = 'Federal' THEN ISNULL(stg.[Interest], 0) ELSE 0 END) AS [FederalInterest]
,MAX(CASE WHEN Flag = 'Provincial' THEN ISNULL(stg.[Interest], 0) ELSE 0 END) AS [ProvincialInterest]
FROM
[stg].[TableA] stg
where LoanNumber = 400799074
GROUP BY
stg.Number
我得到的输出是
Number FederalValue ProvincialValue FederalIntrest ProvincialInterest
400799074 12540.8 248.97 0 0
我遗漏了一些东西,因为我不明白为什么 ProvincialInterest 是 0 而不是 -0.01
stg table 中的数据类型是 float,目标 table 是 decimal(15,2)。
当我删除 else 条件时,我得到了正确的结果,但我无法删除它们,因为在某些情况下,“provincial”行将不存在。
,MAX(CASE WHEN Flag = 'Provincial' THEN ISNULL(stg.[Interest], 0) /*ELSE 0 removed */ END) AS [ProvincialInterest]
快速示例数据
declare @tableA table
(
Flag nvarchar(20),
Number nvarchar(20),
Value money,
Interest money
);
insert into @tableA (Flag, Number, Value, Interest) values
('Federal', '0400799074', 12540.80, 0.0),
('Provincial', '0400799074', 248.97, -0.01),
('Federal', '0423456789', 123.45, 10.0); --Number without Provincial level
快速而肮脏的解决方案
在包含负值的数据集上获取最大值时,不应将未知 (null
) 值替换为 0(ISNULL(..., 0)
部分)。相反,您应该使用该数据类型的最小值。这里我只是用-99999
来证明'large negative value'点。
select Number
,MAX(CASE WHEN Flag = 'Federal' THEN ISNULL(stg.[Value], 0) ELSE -99999 END) AS [FederalValue]
,MAX(CASE WHEN Flag = 'Provincial' THEN ISNULL(stg.[Value], 0) ELSE -99999 END) AS [ProvincialValue]
,MAX(CASE WHEN Flag = 'Federal' THEN ISNULL(stg.[Interest], 0) ELSE -99999 END) AS [FederalInterest]
,MAX(CASE WHEN Flag = 'Provincial' THEN ISNULL(stg.[Interest], 0) ELSE -99999 END) AS [ProvincialInterest]
FROM @tableA stg
group by stg.Number;
此查询的结果具有所需 -0.01
,但还包含替换值 -99999.00
,仍必须对其进行处理才能获得请求的结果。
更好的解决方案
如果您不知道数据值的全部范围,则可能很难确定合适的负替换值(例如 -99999
)。因此我建议让 MAX()
函数处理未知数 (NULL
)。提示:该函数会忽略它们...最后一步替换任何 NULL
值。这意味着将 ISNULL()
函数移到 MAX()
函数之外。
select Number
,ISNULL(MAX(CASE WHEN Flag = 'Federal' THEN stg.[Value] END), 0) AS [FederalValue]
,ISNULL(MAX(CASE WHEN Flag = 'Provincial' THEN stg.[Value] END), 0) AS [ProvincialValue]
,ISNULL(MAX(CASE WHEN Flag = 'Federal' THEN stg.[Interest] END), 0) AS [FederalInterest]
,ISNULL(MAX(CASE WHEN Flag = 'Provincial' THEN stg.[Interest] END), 0) AS [ProvincialInterest]
from @tableA stg
group by stg.Number;
样本结果
更好 解决方案的结果。
Number FederalValue ProvincialValue FederalInterest ProvincialInterest
-------------------- --------------------- --------------------- --------------------- ---------------------
0400799074 12540,80 248,97 0,00 -0,01
0423456789 123,45 0,00 10,00 0,00