Sql 按多个标签选择(白名单和黑名单)
我的结构如下:Sql 按多个标签选择(白名单和黑名单),sql,sqlite,Sql,Sqlite,我的结构如下: CREATE TABLE stories ( id INTEGER PRIMARY KEY AUTOINCREMENT, dir TEXT, alias TEXT, title TEXT ); CREATE TABLE tags ( story_id INTEGER, name TEXT ); 现在,我想选择所有有(至少)给定N个标记的故事,而没有其他N个标记 示例:所有故事都有“幻想”和“自然”,但没有“龙” 这里有一个我尝试过的查询(目前只是“白名
CREATE TABLE stories
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
dir TEXT,
alias TEXT,
title TEXT
);
CREATE TABLE tags
(
story_id INTEGER,
name TEXT
);
现在,我想选择所有有(至少)给定N个标记的故事,而没有其他N个标记
示例:所有故事都有“幻想”和“自然”,但没有“龙”
这里有一个我尝试过的查询(目前只是“白名单”部分,但速度非常慢——所以我肯定我做得不对
SELECT s.*
FROM stories s
WHERE
(SELECT COUNT(*)
FROM tags t
WHERE
t.story_id = s.id
AND t.name IN ('fantasy', 'nature')
) = 2
如果我在最后加上“限制10”,它会起作用(但速度很慢)
但是,不知道如何将黑名单条件包括到查询中
想法
我有大约20000个故事和75000个标记条目。这可以通过子查询轻松完成:
SELECT ...
FROM stories
WHERE id IN (SELECT story_id FROM tags WHERE name = 'fantasy')
AND id IN (SELECT story_id FROM tags WHERE name = 'nature' )
AND id NOT IN (SELECT story_id FROM tags WHERE name = 'dragons');
或者,使用组合标记过滤器:
SELECT ...
FROM stories
WHERE id IN (SELECT story_id FROM tags WHERE name = 'fantasy'
INTERSECT
SELECT story_id FROM tags WHERE name = 'nature'
EXCEPT
SELECT story_id FROM tags WHERE name = 'dragons');
哪一个更快取决于要检查的标签数量,以及过滤器的选择性;您必须尝试
如果
tags.name
列上有索引,则这两个查询都是有效的。如果需要点,请回答,但我已经用另一种方法解决了这一问题,在所有标记连接的列上使用LIKE查询。