SQL 根据多行列中的数据查询到 select 结果 - 基于标签的词组搜索
SQL query to select result based on data from column in multiple rows - phrase search based on tags
所以我有一个小图片库,我开始使用标签来增强它。我决定采用最简单的解决方案,我有一个 table 就像:
describe photo_tags;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| photoid | bigint(20) | NO | PRI | NULL | |
| tag | varchar(32) | NO | PRI | NULL | |
+---------+-------------+------+-----+---------+-------+
它有效,我有 photoid 的唯一索引,标签对避免重复,通常它会做预期的事情,但有一件烦人的事:我希望能够不仅通过单个标签进行搜索,而且能够通过一个标签进行搜索短语。
查询(下面的示例)由 PHP 基于使用 str_word_count 处理过的经过清理的查询字符串生成。
举个例子,这里是 DB 中实际条目的片段
+---------+-----------------------+
| photoid | tag |
+---------+-----------------------+
| 8717 | red |
| 8717 | road |
| 8717 | sky |
| 8717 | tanker |
| 8717 | trees |
| 8717 | truck |
| 8717 | truck on truck action |
| 8717 | vehicle |
| 18858 | clouds |
| 18858 | green |
| 18858 | park |
| 18858 | sky |
| 18858 | trees |
| 18858 | truck |
| 18858 | vehicle |
| 18858 | walkway |
+---------+-----------------------+
假设我想根据标签“红色卡车”搜索图库:
这显然行不通
select photoid from photo_tags where tag="red truck" or (tag="red" and tag="truck");
这将有点工作:
select photoid from photo_tags where tag="red truck" or tag in('red','truck');
但它基本上会 select 明显有红色或卡车的 photoid,不一定两者都有。
有没有人知道如何在不修改底层 table 的情况下改进查询。或者也许还有另一种方法可以实现我想要做的事情?我正在使用 MariaDB 10.3 和 PHP 7.3(基本上是 Debian 10 中的版本)
我想你想要聚合:
select photoid
from photo_tags
where tag in ('red', 'truck')
group by photoid
having count(*) = 2;
如果你也能有'red truck'
,那么:
select photoid
from photo_tags
group by photoid
having sum(tag in ('red', 'truck')) = 2 or
sum(tag = 'red truck') > 0;
所以我有一个小图片库,我开始使用标签来增强它。我决定采用最简单的解决方案,我有一个 table 就像:
describe photo_tags;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| photoid | bigint(20) | NO | PRI | NULL | |
| tag | varchar(32) | NO | PRI | NULL | |
+---------+-------------+------+-----+---------+-------+
它有效,我有 photoid 的唯一索引,标签对避免重复,通常它会做预期的事情,但有一件烦人的事:我希望能够不仅通过单个标签进行搜索,而且能够通过一个标签进行搜索短语。
查询(下面的示例)由 PHP 基于使用 str_word_count 处理过的经过清理的查询字符串生成。
举个例子,这里是 DB 中实际条目的片段
+---------+-----------------------+
| photoid | tag |
+---------+-----------------------+
| 8717 | red |
| 8717 | road |
| 8717 | sky |
| 8717 | tanker |
| 8717 | trees |
| 8717 | truck |
| 8717 | truck on truck action |
| 8717 | vehicle |
| 18858 | clouds |
| 18858 | green |
| 18858 | park |
| 18858 | sky |
| 18858 | trees |
| 18858 | truck |
| 18858 | vehicle |
| 18858 | walkway |
+---------+-----------------------+
假设我想根据标签“红色卡车”搜索图库:
这显然行不通
select photoid from photo_tags where tag="red truck" or (tag="red" and tag="truck");
这将有点工作:
select photoid from photo_tags where tag="red truck" or tag in('red','truck');
但它基本上会 select 明显有红色或卡车的 photoid,不一定两者都有。
有没有人知道如何在不修改底层 table 的情况下改进查询。或者也许还有另一种方法可以实现我想要做的事情?我正在使用 MariaDB 10.3 和 PHP 7.3(基本上是 Debian 10 中的版本)
我想你想要聚合:
select photoid
from photo_tags
where tag in ('red', 'truck')
group by photoid
having count(*) = 2;
如果你也能有'red truck'
,那么:
select photoid
from photo_tags
group by photoid
having sum(tag in ('red', 'truck')) = 2 or
sum(tag = 'red truck') > 0;