假设我有以下三个表来表达一个关系,在这些关系中,帖子被赋予了标签(多对多关系):
create table posts (id integer, content text, primary key (id)); create table tags (tag varchar(30), description text, primary key (tag)); create table post_tags (post_id integer, tag varchar(10), primary key (post_id, tag), foreign key (post_id) references posts (id), foreign key (tag) references tags (tag));
现在,假设我想查找所有带有标签{clever,interesting}且没有其他标签的帖子。
这是我失败的尝试。它查找带有标签{clever,interesting}的帖子,但也查找具有标签{clever,interesting,annoying}或{clever,interesting,unthical}的帖子。
select t1.post_id from post_tags as t1 inner join post_tags as t2 on t2.post_id=t1.post_id where t1.tag='clever' and t2.tag='interesting';
我乐于接受任何有关更改结构以简化此操作的建议。但是,我想避免在posts表中添加以逗号分隔的标签列表之类的事情。
posts
这是一个精确的关系划分问题。
在SQL Server中,一种性能良好的方法(假设对的唯一约束post_id,tag)是
post_id,tag
SELECT post_id FROM post_tags GROUP BY post_id HAVING MIN(CASE WHEN Keyword IN ( 'clever', 'interesting' ) THEN 1 ELSE 0 END) = 1 AND SUM(CASE WHEN Keyword IN ( 'clever', 'interesting' ) THEN 1 ELSE 0 END) = 2
因此,我不排除使用GROUP_CONCATin的想法HAVING。
GROUP_CONCAT
HAVING
HAVING GROUP_CONCAT(DISTINCT Keyword ORDER BY Keyword) = 'clever,interesting'