我不是数据库程序员,但我有一个简单的数据库支持的应用程序,其中有带有标签的项目。每个项目可能有多个标签,因此我使用典型的联结表(如 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”,因为它不需要 SELECT
的 FROM
子句。
这假设一个标签只能被分配一次。如果不是这种情况,您需要在 having
子句中使用 count(distinct id)
。
关于获取 "and"多行匹配列表的 SQL 模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12043395/