【问题标题】:Pivot using Max in Azure DW(Synapse)在 Azure DW(突触)中使用 Max 进行数据透视
【发布时间】:2020-11-11 03:59:02
【问题描述】:

我在 azure sql dw 中遇到了一个奇怪的问题。我在暂存表中有 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

下面是透视和填充我的目标表的查询

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表中的数据类型是float,目标表是decimal(15,2)。

当我删除 else 条件时,我得到了正确的结果,我无法删除它们,因为会有“省”行不存在的情况。

,MAX(CASE WHEN Flag = 'Provincial' THEN ISNULL(stg.[Interest], 0) /*ELSE 0  removed */ END) AS [ProvincialInterest]

【问题讨论】:

    标签: azure tsql pivot azure-synapse


    【解决方案1】:

    快速样本数据

    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来证明'大负值'点。

    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
    

    【讨论】:

    • “更好的解决方案”有效,但“快速而肮脏的解决方案”仍然将“ProvincialIntrest”显示为 0 而不是 -0.01
    • @sab 你是对的,我修改了我的答案以反映这一点!只有“更好的解决方案”才能立即产生所需的结果。
    猜你喜欢
    • 1970-01-01
    • 2020-10-02
    • 2023-04-04
    • 1970-01-01
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    相关资源
    最近更新 更多