MySQL: обновление строк в таблице путем итерации и объединения с другой - PullRequest
2 голосов
/ 03 апреля 2011

У меня есть таблица paper

CREATE TABLE `papers` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(1000) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `my_count` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  FULLTEXT KEY `title_fulltext` (`title`),
) ENGINE=MyISAM AUTO_INCREMENT=1617432 DEFAULT CHARSET=utf8 COLLATE=utf8_bin

и другая таблица link_table

CREATE TABLE `auth2paper2loc` (
  `auth_id` int(11) NOT NULL,
  `paper_id` int(11) NOT NULL,
  `loc_id` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

Идентификатор paper.id из верхней таблицы такой же, как и link_table.paper_id ввторой столЯ хочу перебрать каждую строку в верхней таблице и подсчитать, сколько раз этот его идентификатор появляется во второй таблице, и сохранить «count» в столбце «my_count» в верхней таблице.

Пример: ЕслиБумага с tid = 1 = paper_id появляется 5 раз в таблице link_table, затем my_count = 5.

Я могу сделать это с помощью скрипта Python, но это приводит к слишком большому количеству запросов, и у меня миллионы записей, поэтомудействительно медленно.И я не могу понять правильный синтаксис, чтобы сделать это прямо в MySQL.

Это то, что я повторяю в цикле for в Python (слишком медленно):

SELECT count(link_table.auth_id) FROM link_table
WHERE link_table.paper_id = %s

UPDATE papers SET auth_count = %s WHERE id = %s

Может кто-нибудь сказать, пожалуйста, как создать этот?Должен быть способ вложить это и поместить его непосредственно в MySQL, чтобы он был быстрее, не так ли?

Ответы [ 3 ]

2 голосов
/ 04 апреля 2011

Как это работает для вас?

update papers a
   set my_count = (select count(*) 
                     from auth2paper2loc b
                    where b.paper_id = a.id);
1 голос
/ 04 апреля 2011
update papers left join 
 (select paper_id, count(*) total from auth2paper2loc group by paper_id) X
 on papers.id = X.paper_id
set papers.my_count = IFNULL(X.total, 0)
1 голос
/ 04 апреля 2011

Используйте либо:

UPDATE PAPERS
   SET my_count = (SELECT COUNT(b.paper_id)
                     FROM AUTH2PAPERLOC b
                    WHERE b.paper_id = PAPERS.id)

... или:

   UPDATE PAPERS
LEFT JOIN (SELECT b.paper_id,
                  COUNT(b.paper_id) AS numCount
             FROM AUTH2PAPERLOC b
         GROUP BY b.paper_id) x ON x.paper_id = PAPERS.id
      SET my_count = COALESCE(x.numCount, 0)

COALESCE необходимо для преобразования NULL в ноль, когда нет никаких экземпляровPAPERS.id в таблице AUTH2PAPERLOC.

...