【问题标题】:MySQL: Matching inexact values using "ON"MySQL:使用“ON”匹配不精确的值
【发布时间】:2010-04-15 23:22:32
【问题描述】:

我在这里已经超出了我的水平......

我有一个映射表 (table1),用于将特定值 (value) 分配给整数 (map_nu)。我的第二个表 (table2) 是每个用户 (user_id) 的平均值 (avg) 的集合。

我不知道如何正确制作降价表,请随时编辑!

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

谢谢!

【问题讨论】:

    标签: mysql join rounding


    【解决方案1】:

    我认为您可能必须在 2 个单独的查询中执行此操作。 sql 中没有“最近”运算符,因此您可以在软件中计算它,也可以使用

    select map_nu from table1 ORDER BY abs(value - $avg) LIMIT 1
    

    在循环中。但是,它不能用作连接函数,因为它需要 ORDER 和 LIMIT,它们作为连接无效。

    另一种看待它的方式是,您的 map_nu 和 value 似乎是相互确定的 - value = 1 + ((map_nu - 1) * 0.045) - 所以也许您可以利用这一事实并根据该等式计算一个整数?假设关系对 map_nu 的所有值都成立。

    【讨论】:

    • 不幸的是,这种关系在整个映射表中并不成立。我将进行一些编辑以澄清,如果您有任何其他想法,请告诉我。谢谢
    • 我认为您唯一的选择就是在循环中进行。
    【解决方案2】:

    这是一个尴尬的数据库设计。数据代表什么,您要解决什么问题?可能有更好的方法。

    【讨论】:

    • 有些元素我已对其进行了编辑以简化,但我认为我已经过度简化了。我将对问题进行一些编辑。让我知道这是否使它更清楚。
    • 这可能对其他类型的贡献者不公平,但是 - 考虑到这个问题是一年前的,我早就继续前进了,很明显这个问题不够彻底或问对了信息。选择这个答案!谢谢:)
    【解决方案3】:

    也许做一些类似...

    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 中运行或者是否更好地在 MySQL 之外进行。

    注意 2:如果有 avg 值与 table1 内的 value 值等距,则会产生重复的行(例如,如果 valuemap_nu 的 11 和 12 是 2 并且3 并且有人得到 2.5 的 avg)。您的问题并没有真正指定为此做什么,因此您可能需要考虑到这一点。

    【讨论】:

    • 我正在考虑您的建议。但是-供将来参考(我是 Stock Overflow 的新手)-使用 Markdown 并制作像上面那样的表格的快速方法是什么?
    • 我...呃,从 sqlyog 复制粘贴它并缩进它以使其成为代码示例 XD
    【解决方案4】:

    这需要一些额外的工作,但我认为获得结果的最简单方法是将所有值映射到 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
    ...
    

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

    【讨论】:

      猜你喜欢
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 2011-08-10
      • 1970-01-01
      • 1970-01-01
      • 2021-02-19
      • 2016-02-28
      • 2021-11-16
      相关资源
      最近更新 更多