我离开了联盟......
我有一个映射表(table1)来将特定值(值)分配给整数(map_nu)。我的第二个表(table2)是每个用户(user_id)的平均值(平均值)的集合。
(我无法弄清楚如何正确制作降价表,请随时修改!)
table1: table2:
(value)(Map_nu) (user_id)(avg)
---- -----
1 1 1 1.111
1.045 2 2 1.2
1.09 3 3 1.33333
1.135 4 4 1
1.18 5 5 1.389
1.225 6 6 1.42
1.27 7 7 1.07
1.315 8
1.36 9
1.405 10
值Map_nu是一个特殊数字,每个用户根据其平均值分配。我需要找到一种方法来匹配table2中的平均值到table1中最接近的值。我只需要匹配小数点后的2位数,所以我添加了截断函数
SELECT table2.user_id, map_nu
FROM `table1`
JOIN table2 ON TRUNCATE(table1.value,2)=TRUNCATE(table2.avg,2)
我仍然错过了与平均值完全不符的值。有没有办法选择最接近的截断值,甚至是舍入到第二个小数?只要它应用于所有值相同,向上/向下舍入就不重要了。
我试图得到以下结果(如果四舍五入):
(user_id)(Map_nu)
----
1 4
2 6
3 6
4 1
5 10
6 11
7 3
谢谢!
答案 0 :(得分:1)
我认为您可能需要在2个单独的查询中执行此操作。 sql中没有'nearest'运算符,因此您可以在软件中计算它,也可以使用
select map_nu from table1 ORDER BY abs(value - $avg) LIMIT 1
在循环中。但是,它不能用作连接函数,因为它需要ORDER和LIMIT作为连接无效。
另一种看待它的方式是,你的map_nu和值似乎是相对于彼此的确定性的 - value = 1 + ((map_nu - 1) * 0.045)
- 所以也许你可以利用这个事实并根据这个等式计算一个整数?假设该关系对于map_nu的所有值都适用。
答案 1 :(得分:0)
这是一个尴尬的数据库设计。表示什么是数据以及您要解决的是什么?可能有更好的方法。
答案 2 :(得分:0)
也许做点什么......
SELECT a.user_id, b.map_nu, abs(a.avg - b.value)
FROM
table2 a
join table1 b
left join table1 c on abs(a.avg - b.value) > abs(a.avg - c.value)
where c.value is null
order by a.user_id
实际上不会产生与您期望的输出相同的输出(不进行任何舍入)。虽然你应该能够从那里调整它。上面的查询将产生下面的输出(w /您提供的数据):
user_id map_nu abs(a.avg - b.value)
------- ------ --------------------
1 3 0.0209999999999999
2 5 0.02
3 8 0.01833
4 1 0
5 10 0.016
6 10 0.0149999999999999
7 3 0.02
请注意,如果您正在处理大型表格。评估上述查询的解释,如果在MySQL中运行它是否切实可行,或者更好地在它之外完成。
注意2:如果avg
值等于value
table1
范围内的value
值,则会生成重复行(例如map_nu
avg
11和12分别是2和3,有人得到2.5的{{1}}。你的问题并没有真正指明该怎么做,所以你可能想要考虑到这一点。
答案 3 :(得分:0)
它需要额外的工作,但我认为获得结果的最简单方法是将所有值映射到table1中的第二个小数位:
1 1
1.01 1
1.02 1
1.03 1
1.04 1
1.05 2
1.06 2
1.07 2
1.08 2
1.09 3
1.1 3
1.11 3
1.12 3
1.13 3
1.14 4
...
感谢您的建议!对不起,我无法更清楚地提出问题。