MySQL: сопоставление неточных значений с использованием «ON» - PullRequest
0 голосов
/ 16 апреля 2010

Я далеко от своей лиги здесь ...

У меня есть таблица сопоставления (table1) для назначения определенных значений (value) целому числу (map_nu). Моя вторая таблица (table2) - это набор средних значений (avg) для каждого пользователя (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 - это специальный номер, который каждому пользователю присваивается в соответствии с его средним значением. Мне нужно найти способ сопоставить средние значения из таблицы2 с ближайшим значением в таблице1. Мне нужно сопоставить только две цифры после десятичной дроби, поэтому я добавил усеченную функцию

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 ]

1 голос
/ 16 апреля 2010

Я думаю, что вам, возможно, придется сделать это в 2 отдельных запроса. в sql нет «ближайшего» оператора, так что вы можете либо вычислить его в своем программном обеспечении, либо использовать

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.

0 голосов
/ 16 апреля 2010

Требуется немного больше работы, но я думаю, что самый простой способ получить мои результаты - сопоставить все значения со вторым десятичным знаком в таблице1:

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

Спасибо за предложения! Извините, я не смог представить вопрос более четко.

0 голосов
/ 16 апреля 2010

Может быть сделать что-то вроде ...

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

На самом деле не выдает того же результата, который вы ожидали (округление не выполняется). Хотя вы должны быть в состоянии настроить его оттуда. Приведенный выше запрос приведет к выводу ниже (с предоставленными вами данными):

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 '11 и 12 равны 2 и 3 и кто-то получает avg из 2,5). Ваш вопрос на самом деле не указывает, что для этого нужно сделать, поэтому вы можете принять это во внимание.

0 голосов
/ 16 апреля 2010

Это неуклюжий дизайн базы данных. Что представляют собой данные и что вы пытаетесь решить? Там может быть лучший способ.

...