我有以下结构:
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
如果我在末尾添加“ LIMIT 10”,它会起作用(但速度很慢)。
不过,不知道如何将黑名单条件包括到查询中。
有想法吗?
我有大约20.000个故事和75,000个标签条目。
最佳答案
这可以通过子查询轻松完成:
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');
或者,使用compound query组合标签过滤器:
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
列上有索引,则这两个查询都是有效的。
关于sql - 按多个标签选择(白名单和黑名单),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32574763/