Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 按多个标签选择(白名单和黑名单)_Sql_Sqlite - Fatal编程技术网

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查询。