我有以下表格:
CREATE TABLE `content` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`content` varchar(255) NOT NULL,
`tag_a_id` int unsigned DEFAULT NULL,
`tag_b_id` int unsigned DEFAULT NULL,
`tag_c_id` int unsigned DEFAULT NULL,
`tag_d_id` int unsigned DEFAULT NULL,
`tag_e_id` int unsigned DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `tags` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`tag` varchar(32) NOT NULL UNIQUE,
PRIMARY KEY (`id`)
);
该tags
表与内容表具有一对多的关系,使用tag_?_id
字段,但每个标签 ID 每行仅出现一次。
我想做一个查询,从content
表中选择与给定标签集(以及所有相关标签)关联的所有行。例如,“获取所有与标签“新闻”和“医疗保健”相关联的内容行。
这意味着需要在tags
表中查找“News”和“MedicalCare”的 ID,然后使用这样的一对查询将其注入到content
表上的查询中(假设这些标签具有 ID45
和68
):
SELECT id FROM tags WHERE tag IN ("News","MedicalCare");
... 进而...
SELECT t1.id, t1.content, ts_a.tag, ts_b.tag, ts_c.tag, ts_d.tag, ts_e.tag
FROM (
SELECT t.id, t.content, t.tag_a_id, t.tag_b_id, t.tag_c_id, t.tag_d_id, t.tag_e_id
FROM content t
WHERE 45 IN (t.tag_a_id, t.tag_b_id, t.tag_c_id, t.tag_d_id, t.tag_e_id)
AND 68 IN (t.tag_a_id, t.tag_b_id, t.tag_c_id, t.tag_d_id, t.tag_e_id)
ORDER BY t.id ASC LIMIT 200
) t1
LEFT JOIN tags ts_a ON t1.tag_a_id=ts_a.id
LEFT JOIN tags ts_b ON t1.tag_b_id=ts_b.id
LEFT JOIN tags ts_c ON t1.tag_c_id=ts_c.id
LEFT JOIN tags ts_d ON t1.tag_d_id=ts_d.id
LEFT JOIN tags ts_e ON t1.tag_e_id=ts_e.id;
有没有一种方法可以在此查询中获取我感兴趣的标签 ID ,并动态生成那些 AND x IN (a,b,c) 子句?
另一种选择可能是这样的:
WHERE EVERY ONE OF (
SELECT id FROM tags WHERE tag IN ("News","MedicalCare")
) IN (t.tag_a_id, t.tag_b_id, t.tag_c_id, t.tag_d_id, t.tag_e_id)
请注意:该content
表非常大,因此如果不先过滤掉不需要的行并应用LIMIT
.