Select X #s from list that average Y
Select X #s from list that average Y
我有一个号码列表。我需要找到一种方法来 select X 的平均数约为 Y。
举个简单的例子,假设我的列表是:
30, 40, 50, 60, 70, 80, 90, 100, 110
我需要找到三个平均约为 70 的数字的组合。可能的解决方案可能是 60, 70, 80
或 50, 70, 90
或 30, 70, 110
.
老实说,我什至不知道如何开始,所以恐怕我没有尝试太多。我检查了 Excel 求解器,但无法找到具有 'or' 约束的方法。
我很擅长在 Excel 中使用 VBA 并编写 SQL 代码,但我不知道如何使用这些技能中的任何一个来破解这个问题。
有人知道如何在 Excel 或 SSMS 中解决这个问题吗?如果没有,我应该探索哪些其他选项?
我有一个可能的解决方案:
- 将您的值填充到数组中
- 计算你的平均值
- 查找数组中的精确值或近似值。
- 获取值,后 1 个值和前 1 个值。
您可以更改第 4 点的条件。
DECLARE @Table AS TABLE (I INT)
INSERT INTO @Table VALUES (30),(40),(50),(60),(70),(80),(90),(100),(110)
SELECT
DISTINCT
N1 = CASE
WHEN t1.I < t2.I AND t1.I < t3.I THEN t1.I
WHEN t2.I < t1.I AND t2.I < t3.I THEN t2.I
ELSE t3.I
END
,N2 = CASE
WHEN t1.I > t2.I AND t1.I < t3.I THEN t1.I
WHEN t1.I < t2.I AND t1.I > t3.I THEN t1.I
WHEN t2.I > t1.I AND t2.I < t3.I THEN t2.I
WHEN t2.I < t1.I AND t2.I > t3.I THEN t2.I
ELSE t3.I
END
,N3 = CASE
WHEN t1.I > t2.I AND t1.I > t3.I THEN t1.I
WHEN t2.I > t1.I AND t2.I > t3.I THEN t2.I
ELSE t3.I
END
FROM
@Table t1
CROSS JOIN @Table t2
CROSS JOIN @Table t3
WHERE
t1.I <> t2.I
AND t1.I <> t3.I
AND t2.I <> t3.I
AND (SELECT AVG(V) FROM (VALUES(t1.I),(t2.I),(t3.I)) t(V)) = (SELECT AVG(I) FROM @Table)
基本上,您必须查看 3 个数字的所有可能组合,以确定平均值是否为 70。如果您的 table 很大,这可能会对系统资源造成极大的负担。会有一些限制它以减少开销,例如查看所有 3 个数字是否小于平均值或大于平均值。等。当您进行所有组合时,您还会得到重复的 pairs/rows,因此您必须以这种方式对值进行排序,以便获得不同的值。比如第一个column/number最小,第二个第二个,第三个最大...
这是基于我的评论的 SQL 方法:
SELECT t.n
FROM t
ORDER BY ABS(t.n-70) ASC
LIMIT 3;
假设您想要 3 个平均值接近 70 的数字。
希望对您有所帮助。
我有一个号码列表。我需要找到一种方法来 select X 的平均数约为 Y。
举个简单的例子,假设我的列表是:
30, 40, 50, 60, 70, 80, 90, 100, 110
我需要找到三个平均约为 70 的数字的组合。可能的解决方案可能是 60, 70, 80
或 50, 70, 90
或 30, 70, 110
.
老实说,我什至不知道如何开始,所以恐怕我没有尝试太多。我检查了 Excel 求解器,但无法找到具有 'or' 约束的方法。
我很擅长在 Excel 中使用 VBA 并编写 SQL 代码,但我不知道如何使用这些技能中的任何一个来破解这个问题。
有人知道如何在 Excel 或 SSMS 中解决这个问题吗?如果没有,我应该探索哪些其他选项?
我有一个可能的解决方案:
- 将您的值填充到数组中
- 计算你的平均值
- 查找数组中的精确值或近似值。
- 获取值,后 1 个值和前 1 个值。
您可以更改第 4 点的条件。
DECLARE @Table AS TABLE (I INT)
INSERT INTO @Table VALUES (30),(40),(50),(60),(70),(80),(90),(100),(110)
SELECT
DISTINCT
N1 = CASE
WHEN t1.I < t2.I AND t1.I < t3.I THEN t1.I
WHEN t2.I < t1.I AND t2.I < t3.I THEN t2.I
ELSE t3.I
END
,N2 = CASE
WHEN t1.I > t2.I AND t1.I < t3.I THEN t1.I
WHEN t1.I < t2.I AND t1.I > t3.I THEN t1.I
WHEN t2.I > t1.I AND t2.I < t3.I THEN t2.I
WHEN t2.I < t1.I AND t2.I > t3.I THEN t2.I
ELSE t3.I
END
,N3 = CASE
WHEN t1.I > t2.I AND t1.I > t3.I THEN t1.I
WHEN t2.I > t1.I AND t2.I > t3.I THEN t2.I
ELSE t3.I
END
FROM
@Table t1
CROSS JOIN @Table t2
CROSS JOIN @Table t3
WHERE
t1.I <> t2.I
AND t1.I <> t3.I
AND t2.I <> t3.I
AND (SELECT AVG(V) FROM (VALUES(t1.I),(t2.I),(t3.I)) t(V)) = (SELECT AVG(I) FROM @Table)
基本上,您必须查看 3 个数字的所有可能组合,以确定平均值是否为 70。如果您的 table 很大,这可能会对系统资源造成极大的负担。会有一些限制它以减少开销,例如查看所有 3 个数字是否小于平均值或大于平均值。等。当您进行所有组合时,您还会得到重复的 pairs/rows,因此您必须以这种方式对值进行排序,以便获得不同的值。比如第一个column/number最小,第二个第二个,第三个最大...
这是基于我的评论的 SQL 方法:
SELECT t.n
FROM t
ORDER BY ABS(t.n-70) ASC
LIMIT 3;
假设您想要 3 个平均值接近 70 的数字。
希望对您有所帮助。