繁体   English   中英

获取同一行上 3 列之间的最小值

[英]Get MIN value between 3 columns on same row

虽然我已经为我正在寻找的东西提出了几个可行的解决方案,但我想知道是否有更简化的方法来确定单行中的 3 列中的哪一列包含最小/最小值。 以下是我正在使用的数据示例:

账号 工作 自上次销售以来的天数 自上次充电后的天数 成立天数
YO502 NULL NULL 5283 NULL
YO525 NULL 2303 2303 5917
ZE100 1个 190 449 707
ZE100 2个 160 279 615
ZI402 NULL 2109 2109 NULL

结果会是什么,这只是 DaysInactive 的新列,其中包含 3 个非空 DaysSincexxx 值中的较小者:

账号 工作 自上次销售以来的天数 自上次充电后的天数 成立天数 不活动天数
YO502 NULL NULL 5283 NULL 5283
YO525 NULL 2303 2303 5917 2303
ZE100 1个 190 449 707 190
ZE100 2个 160 279 615 160
ZI402 NULL 2109 2109 NULL 2109

这就是我所必须的,只是使用一系列 CASE 表达式来比较它们。 目标是根据与工作相关的 3 个不同日期值中的任何一个,找到客户工作不活动天数的最低值。 需要明确的是,其中 2 列(DaysSinceLastSale 和 DaysSinceLastCharge)是主要目标,第 3 列(DaysSinceEstablished)是最后的手段,如果前 2 列是 NULL(所有 3 列实际上可以是 NULL,在这种情况下我们默认为 99999)。 我最终在 PowerBI 报告中使用了它,因此可以为最终用户设置 >= 切片器以手动输入记录应该具有的最小非活动天数,以便在报告视觉上返回:

SELECT 
    CASE 
        WHEN COALESCE(DaysSinceLastSale, DaysSinceLastCharge) IS NOT NULL THEN 
            CASE WHEN COALESCE(DaysSinceLastSale, DaysSinceLastCharge) <= COALESCE(DaysSinceLastCharge, DaysSinceLastSale)  
                THEN COALESCE(DaysSinceLastSale, DaysSinceLastCharge) 
                ELSE COALESCE(DaysSinceLastCharge, DaysSinceLastSale) 
            END
        ELSE  COALESCE(DaysSinceEstablished, 99999) 
        END as DaysInactive
    , DS.*  
FROM #DS2 DS 

这是我最初的解决方案,但我只是不喜欢所有的子查询和 UNION:

SELECT 
    NormalizedDaysInactive.DaysInactive
    , DS.* 
FROM #DS2 DS 
JOIN (
    SELECT 
        AccountNumber, BillingLevel, Job, MIN(ISNULL(DaysInactive, 99999)) as DaysInactive 
    FROM
    (
        SELECT AccountNumber, BillingLevel, Job, MIN(DaysSinceLastSale) as DaysInactive FROM #DS2 GROUP BY AccountNumber, BillingLevel, Job
        UNION ALL
        SELECT AccountNumber, BillingLevel, Job, MIN(DaysSinceLastCharge) as DaysInactive FROM #DS2 GROUP BY AccountNumber, BillingLevel, Job
        UNION ALL
        SELECT AccountNumber, BillingLevel, Job, MIN(DaysSinceEstablished) as DaysInactive FROM #DS2 GROUP BY AccountNumber, BillingLevel, Job
    ) ActDays
    GROUP BY AccountNumber, BillingLevel, Job
    HAVING MIN(ISNULL(DaysInactive, 1)) > 0
) NormalizedDaysInactive ON NormalizedDaysInactive.AccountNumber = DS.AccountNumber
    AND (NormalizedDaysInactive.Job = DS.Job OR NormalizedDaysInactive.BillingLevel = 'Account')

感谢任何建议! 谢谢

您可以使用 APPLY 进行一些“内联”逆透视操作,然后获取最小值。 我添加了TypeOfActivity列,它可能会派上用场,以了解什么活动

多列之间的最小值

SELECT *
FROM YourTable AS A
CROSS APPLY (
    SELECT TOP(1) *
    FROM (
        VALUES 
            ('Sale',DaysSinceLastSale)
            ,('Charge',DaysSinceLastCharge)
            ,('Established',DaysSinceEstablished)
    ) AS DTA(TypeOfActivity,DaysSinceActivity)
    WHERE DaysSinceActivity IS NOT NULL
    ORDER BY DaysSinceActivity
) AS B

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM