获取 "and"多行匹配列表的 SQL 模式?

标签 sql sqlite list

我不是数据库程序员,但我有一个简单的数据库支持的应用程序,其中有带有标签的项目。每个项目可能有多个标签,因此我使用典型的联结表(如 this ),其中每一行表示具有适当 ID 的项目具有具有适当 ID 的标签。

当我想要执行诸如选择具有给定标签的所有项目之类的操作时,这非常合乎逻辑。

但是,执行 AND 搜索的典型模式是什么?也就是说,如果我想查找具有所有特定标签集的所有项目,该怎么办?这是一个非常常见的操作,我认为一些介绍教程会涵盖它,但我想我没有在正确的地方寻找。

我尝试的方法是使用INTERSECT,首先直接使用,然后使用子查询和IN。这是可行的,但当我添加搜索词时,会快速建立看似很长的查询。而且,至关重要的是,这种方法似乎比将所有标签作为文本插入一个“标签”列并使用 SQLite 的全文搜索的方法慢一个数量级。 (而且,正如我所期望/希望的那样,当我添加更多术语时,FTS 搜索会变得更快,而 INTERSECTS 方法似乎并非如此。)

这里正确的设计模式是什么?让它变得活泼的正确方法是什么?在本例中我使用的是 SQLite,但我对一般答案最感兴趣,因为这必须是常见的事情。

最佳答案

以下是标准 ANSI SQL 解决方案,它避免了 id 数量和 id 本身同步。

with tag_ids (tid) as (
   values (1), (2)
)
select id
from tags
where id (select tid from tag_ids)
having count(*) = (select count(*) from tag_ids);

PostgreSQL 和 DB2 支持 values 子句(“行构造函数”)。对于不支持该功能的数据库,您可以将其替换为简单的“选择”,例如在 Oracle 中,这将是:

with tag_ids (tid) as (
   select 1 as tid from dual
   union all 
   select 2 from dual
)
select id
from tags
where id (select tid from tag_ids)
having count(*) = (select count(*) from tag_ids);

对于 SQL Server,您只需省略“from Dual”,因为它不需要 SELECTFROM 子句。

这假设一个标签只能被分配一次。如果不是这种情况,您需要在 having 子句中使用 count(distinct id)

关于获取 "and"多行匹配列表的 SQL 模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12043395/

相关文章:

mysql - 与其他 DBMS 相比,MySQL 是否消耗更多资源?

sql - 在 Oracle 中哪里可以找到表的段?

sql - 用于 sql 表中的 "Status"列的类型

sqlite - iOS App中的SQLite DB和表ID

python - 更新字典值中的列表

如果长度从列表中的列表中删除列表

javascript - 使用 JavaScript 对数据进行排序

mysql - 这些索引之间的 SELECT 查询速度差异 : *UNIQUE(col1, col2)* 与 *FK(col1)、FK(col2)*

mysql - 在 MySQL 中创建结构

excel - 从 Excel 批量插入到 SQLite,无需 TXT 或 CSV 文件