【问题标题】:SQL query to select result based on data from column in multiple rows - phrase search based on tagsSQL查询根据多行列中的数据选择结果 - 基于标签的短语搜索
【发布时间】:2020-10-05 14:02:15
【问题描述】:

所以我有一个小的图片库,我开始使用标签来增强它。我决定使用最简单的解决方案,并且我有一张桌子,就像:

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 中实际条目的 sn-p

+---------+-----------------------+
| 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');

但它基本上会选择明显有红色或卡车的photoid,不一定两者都有。

有没有人知道如何在不修改基础表的情况下改进查询。或者也许还有另一种方法可以实现我想要做的事情?我正在使用 MariaDB 10.3 和 PHP 7.3(基本上是 Debian 10 中的)

【问题讨论】:

    标签: mysql sql tags


    【解决方案1】:

    我想你想要聚合:

    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;
    

    【讨论】:

    • 我喜欢它:时尚且易于实施。出于某种原因,当存在唯一键时,分组为我返回了一个空集,但这似乎工作得很好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 2012-08-12
    • 1970-01-01
    相关资源
    最近更新 更多