2011-04-03 107 views
2

加入我有一個表紙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。我想遍歷上表中的每一行,並計算它的id出現在第二個表中的次數,並將「count」存儲在上表中的「my_count」列中。

示例:如果與TID = 1 = paper_id紙張出現5次在表link_table,然後MY_COUNT = 5

我可以做到這一點的一個Python腳本,但它會導致太多querys和我有數以百萬計的人,所以它真的很慢。而且我無法弄清楚正確的語法,以便在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中,以便更快,不是嗎?

回答

1

二者必選其一:

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轉換到零的時候有沒有論文的任何實例。 ID在AUTH2PAPERLOC表中。

+0

當在AUTH2PAPERLOC中找不到'papers.id'的實例時'Count()'返回0。 – Ronnis 2011-04-03 20:55:25

+1

@Ronnis /確切地說,它在第一個查詢中不是必需的。在第二個(通常更快),它是,但有一個語法錯誤 – RichardTheKiwi 2011-04-03 20:58:06

+1

@理查德,是。當我再次閱讀他的答案時,我意識到這個評論意味着第二個查詢。 – Ronnis 2011-04-03 21:03:11

2

這是如何爲您執行的?

update papers a 
    set my_count = (select count(*) 
        from auth2paper2loc b 
        where b.paper_id = a.id); 
1
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)