获取同一行上 3 列之间的最小值
Get MIN value between 3 columns on same row
尽管我已经针对我正在寻找的内容提出了几个可行的解决方案,但我想知道是否有更简化的方法来确定单行中的 3 列中的哪一列包含 smallest/min价值。以下是我正在使用的数据示例:
AccountNumber
Job
DaysSinceLastSale
DaysSinceLastCharge
DaysSinceEstablished
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 值中的较小值:
AccountNumber
Job
DaysSinceLastSale
DaysSinceLastCharge
DaysSinceEstablished
DaysInactive
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 表达式来比较它们。 objective 是根据与作业相关的 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
这是我最初的解决方案,但我只是不喜欢所有的子查询和联合:
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
以及它可能会派上用场以了解 activity 以及
多列之间的最小值
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
尽管我已经针对我正在寻找的内容提出了几个可行的解决方案,但我想知道是否有更简化的方法来确定单行中的 3 列中的哪一列包含 smallest/min价值。以下是我正在使用的数据示例:
AccountNumber | Job | DaysSinceLastSale | DaysSinceLastCharge | DaysSinceEstablished |
---|---|---|---|---|
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 值中的较小值:
AccountNumber | Job | DaysSinceLastSale | DaysSinceLastCharge | DaysSinceEstablished | DaysInactive |
---|---|---|---|---|---|
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 表达式来比较它们。 objective 是根据与作业相关的 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
这是我最初的解决方案,但我只是不喜欢所有的子查询和联合:
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
以及它可能会派上用场以了解 activity 以及
多列之间的最小值
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