Mysql
如何檢查 tag_map GROUP By article_id 中是否存在兩個標籤?
在一個相當簡單
tag_map
的CREATE TABLE tag_map ( article_id int(11) unsigned NOT NULL, tag_id int(11) unsigned NOT NULL, INDEX(tag_id), PRIMARY KEY(article_id,tag_id) ) ENGINE=InnoDB;
如何檢查哪些文章具有此表中給出的標籤對?
CREATE TABLE tag_pairs ( pair_id int(11) unsigned NOT NULL, tag1 int(11) unsigned NOT NULL, tag2 int(11) unsigned NOT NULL, UNIQUE INDEX(tag1,tag2), INDEX(tag2), PRIMARY KEY(pair_id) ) ENGINE=InnoDB;
在範例小提琴中,預期的輸出是:
SELECT article_id,pair_id FROM ... (how to JOIN here) 1 5 1 7 3 6
效率是最重要的,因為桌子很大。
由於
tag_map
相當大,我避免JOIN
在它本身。目前,我SELECT
對每個pair_id
,SELECT article_id, 5 FROM tag_map WHERE tag_id IN(22,23) GROUP BY article_id HAVING SUM(IF(tag_id=22,1,0))>0 AND SUM(IF(tag_id=23,1,0))>0;
這不是有效的。
您的問題是這個問題的一種變體:How to filter SQL results in a has-many-through relationship。閱讀這個問題以及解決這個有趣問題的許多(和不同的)方法。
令人驚訝的是,您的更普遍的問題有一個更簡單的解決方案 - 它涉及三角連接:
select t1.article_id, p.pair_id from tag_map as t1 join tag_map as t2 on t1.article_id = t2.article_id join tag_pairs as p on p.tag1 = t1.tag_id and p.tag2 = t2.tag_id ;
SELECT m1.article_id, m1.tag_id, m2.tag_id FROM tag_map AS m1 JOIN tag_pairs AS p ON p.tag1 = m1.tag_id JOIN tag_map AS m2 ON p.tag2 = m2.tag_id WHERE m2.article_id = m1.article_id;
我將 tag_pairs 更改為
UNIQUE INDEX(pair_id), INDEX(tag2), PRIMARY KEY(tag1,tag2)
但我寧願完全擺脫pair_id。