[英]Get MIN value between 3 columns on same row
Though I have come up with a couple of working solutions to what I am looking for, I am wondering if there is a more streamlined way of determining which of 3 columns from a single row contains the smallest/min value.虽然我已经为我正在寻找的东西提出了几个可行的解决方案,但我想知道是否有更简化的方法来确定单行中的 3 列中的哪一列包含最小/最小值。 Below is an example of the data I am working with:以下是我正在使用的数据示例:
AccountNumber账号 | Job工作 | DaysSinceLastSale自上次销售以来的天数 | DaysSinceLastCharge自上次充电后的天数 | DaysSinceEstablished成立天数 |
---|---|---|---|---|
YO502 YO502 | NULL NULL | NULL NULL | 5283 5283 | NULL NULL |
YO525 YO525 | NULL NULL | 2303 2303 | 2303 2303 | 5917 5917 |
ZE100 ZE100 | 1 1个 | 190 190 | 449 449 | 707 707 |
ZE100 ZE100 | 2 2个 | 160 160 | 279 279 | 615 615 |
ZI402 ZI402 | NULL NULL | 2109 2109 | 2109 2109 | NULL NULL |
And what the outcome would be, which is just the new column of DaysInactive containing the lesser of the 3 non-null DaysSincexxx values:结果会是什么,这只是 DaysInactive 的新列,其中包含 3 个非空 DaysSincexxx 值中的较小者:
AccountNumber账号 | Job工作 | DaysSinceLastSale自上次销售以来的天数 | DaysSinceLastCharge自上次充电后的天数 | DaysSinceEstablished成立天数 | DaysInactive不活动天数 |
---|---|---|---|---|---|
YO502 YO502 | NULL NULL | NULL NULL | 5283 5283 | NULL NULL | 5283 5283 |
YO525 YO525 | NULL NULL | 2303 2303 | 2303 2303 | 5917 5917 | 2303 2303 |
ZE100 ZE100 | 1 1个 | 190 190 | 449 449 | 707 707 | 190 190 |
ZE100 ZE100 | 2 2个 | 160 160 | 279 279 | 615 615 | 160 160 |
ZI402 ZI402 | NULL NULL | 2109 2109 | 2109 2109 | NULL NULL | 2109 2109 |
This is what I have to this point that simply uses a series of CASE expressions to compare them with.这就是我所必须的,只是使用一系列 CASE 表达式来比较它们。 The objective is to find the lowest value of days of inactivity for a client job based on any of 3 different date values tied to the job.目标是根据与工作相关的 3 个不同日期值中的任何一个,找到客户工作不活动天数的最低值。 And to be clear, 2 of the columns (DaysSinceLastSale and DaysSinceLastCharge) are the primary target, with the 3rd (DaysSinceEstablished) being a last resort in the event the first 2 are NULL (All 3 of them can actually be NULL, in which case we default to 99999).需要明确的是,其中 2 列(DaysSinceLastSale 和 DaysSinceLastCharge)是主要目标,第 3 列(DaysSinceEstablished)是最后的手段,如果前 2 列是 NULL(所有 3 列实际上可以是 NULL,在这种情况下我们默认为 99999)。 I am ultimately using this in a PowerBI report so a >= slicer can be setup for the end-users to manually enter the minimum number of inactive days a record should have in order to be returned on the report visual:我最终在 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
This was my original solution but I just didn't like having all the sub-queries and UNIONs:这是我最初的解决方案,但我只是不喜欢所有的子查询和 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')
Appreciate any suggestions!感谢任何建议! Thanks谢谢
You can use APPLY to do a little "inline" unpivot operation and then grab the min value.您可以使用 APPLY 进行一些“内联”逆透视操作,然后获取最小值。 I added the column TypeOfActivity
as well as it might come in handy to know what activity as well我添加了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.