MySQL: Актуализирайте редовете в таблицата чрез повторение и обединяване с друг

Имам документи за маса

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

ID papers.id от горната таблица е същият като link_table.paper_id във втората таблица. Искам да премина през всеки ред в горната таблица и да преброя колко пъти този идентификатор се появява във втората таблица и да съхраня "броя" в колоната "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, така че да е по-бързо, нали?


person Aufwind    schedule 03.04.2011    source източник


Отговори (2)


Използвайте или:

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

...or:

   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.

person OMG Ponies    schedule 03.04.2011
comment
Count() връща 0, когато не са намерени екземпляри на papers.id в AUTH2PAPERLOC. - person Ronnis; 04.04.2011
comment
@Ronnis / точно така, не се изисква в 1-вата заявка. Във 2-ри (който обикновено е по-бърз) е така, но имаше синтактична грешка - person RichardTheKiwi; 04.04.2011
comment
@Ричард, да. Когато чета отговора му още веднъж, осъзнах, че коментарът е предназначен за второто запитване. - person Ronnis; 04.04.2011

Как се представя това за вас?

update papers a
   set my_count = (select count(*) 
                     from auth2paper2loc b
                    where b.paper_id = a.id);
person Ronnis    schedule 03.04.2011