Лучший способ объединить две разные таблицы MySQL - планирование для django из python - PullRequest
1 голос
/ 01 декабря 2009
table a (t_a):
id  name    last    first   email           state   country
0   sklass  klass   steve   sklass@foo.com  in      uk
1   jabid   abid    john    abid@foo.com    ny      us
2   jcolle  colle   john    jcolle@foo.com  wi      us


table b (t_b):
id  sn      given   nick    email           l   c   
0   steven  klass   steve   sklass@foo.com  in  uk
1   john    abid    -       abid_j@foo.com  ny  us
2   johnny  colle   john    jcolle@foo.com  wi  us
3   john    abid    -       abid@foo.com    ny  us

То, что перечислено выше, - это (сокращенно) столбец и строки таблицы MySQL. Глядя на эти две таблицы, становится совершенно ясно, что, строго взглянув на значения (id не просматривается) и сравнив совпадающее число значений, вы получите эти значения.

t_a     t_b
0       0
1       3
2       2
-       1

В конечном итоге я хочу сделать это в Джанго - я не уверен, имеет ли это значение. В прошлом я делал это, используя чистый python, в котором я уничтожал старые данные и просто создавал три новые таблицы. Я хочу отойти от своей реализации (перечисленной ниже), потому что проблемы, которые я вижу, состоят в том, что время меняет вещи, и люди приходят и уходят. В прошлом я только что обновил данные, но теперь я хочу отслеживать, когда люди уходят, а не просто заменять (удалять) данные. Я считаю, что обновление SQL более элегантно и сохраняет историю.

Я хотел бы знать, как получить этот объединенный ответ непосредственно из mySQL (либо функции SQL, либо построения новой таблицы), которая объединяет данные следующим образом. Я хочу сделать это, используя чистый SQL (я думаю, что тогда я могу сделать это в Django). Поэтому я ищу решение, которое соответствует следующим критериям:

  1. Существует min_match, который определяет минимальное количество совпадений между двумя строками, которые должны быть выровнены, чтобы считаться действительными.
  2. Хотя таблицы могут иметь разную длину, это отображение 1: 1. Другими словами, много к одному может и не произойти (пока)

Теперь мой фон - python, и для меня самым простым способом сделать это всегда было создание цикла for для более коротких двух таблиц, который затем выполняет цикл for для другой таблицы, просматривая количество совпадений. В коде это выглядит так.

t_a = [ ["sklass", "klass", "steve", "sklass@foo.com", "in", "uk", ],
        ["jabid", "abid", "john", "abid@foo.com", "ny", "us", ],
        ["jcolle", "colle", "john", "jcolle@foo.com", "wi", "us", ], ]

t_b = [ ["steven", "klass", "steve", "sklass@foo.com", "in", "uk",],
        ["john", "abid", "abid_j@foo.com", "ny", "us",],
        ["johnny", "colle", "john", "jcolle@foo.com", "wi", "us",],
        ["john", "abid", "abid@foo.com", "ny", "us",], ]

min_match = 3

for person_a in t_a:
    match = 0
    match_pct = 0.0
    match_a_index = t_a.index(person_a)
    for person_b in t_b:
        new_match_count = len(list(set(person_a) & set(person_b)))
        if new_match_count > match:
            match = new_match_count
            match_b_index = t_b.index(person_b)
            match_pct = "%.2f" % (float(new_match_count) / \
              float(len(set(person_a + person_b))) * 100)
    if match >= min_match:
        print match_a_index, match_b_index #, match_pct, match

В комментариях возникает вопрос, почему бы вам просто не присоединиться к электронному адресу. Я не обязательно знаю, что значения в столбце будут совпадать. Я уверен, что значения из данной строки в t_a будут совпадать со значениями для строки в t_b. Я хочу, чтобы наибольшее (наиболее вероятное) совпадение для данной строки от t_a до t_b, и только если количество совпадений больше, чем min_match.

1 Ответ

1 голос
/ 01 декабря 2009

Вы можете сделать это в MySQL напрямую через курсор, выполняемый с помощью хранимой процедуры.

DELIMITER $$
CREATE PROCEDURE `proc_name`()
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE a_id BIGINT UNSIGNED;
  DECLARE b_id BIGINT UNSIGNED;
  DECLARE x_count INT;

  -- something like the following
  DECLARE cur1 CURSOR FOR SELECT t_a.id, t_b.id FROM t_a, t_b WHERE t_a.email = t_b.email;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

  SELECT COUNT(*) INTO x_count FROM t_a, t_b WHERE t_a.email = t_b.email;

  IF(x_count > <some_min_value>) THEN

    OPEN cur1;

    REPEAT
      FETCH cur1 INTO a_id, b_id;
      IF NOT done THEN

        -- do something here like update rows, remove rows, etc.
        -- a_id and b_id hold the two id values for the two tables which
        -- I assume to be primary keys

      END IF;
    UNTIL done END REPEAT;

    CLOSE cur1;

  END IF;
END
$$
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...