MySQL:使用“ON”匹配不精确的值

时间:2010-04-15 23:22:32

标签: mysql join rounding

我离开了联盟......

我有一个映射表(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

谢谢!

4 个答案:

答案 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
...

感谢您的建议!对不起,我无法更清楚地提出问题。