首页 > 解决方案 > SQL 查询查找共享相同标签的行

问题描述

让我们看看是否有人可以帮助我...在产品页面上,我必须显示相关产品。这些产品是相关的,取决于它们的标签。例如我的产品(ID 23)有以下标签:烹饪、面条、健康。

我必须做的是一个 SQL 查询,它搜索具有“烹饪、面条、健康”标签但分开的产品

首先搜索标签中有“烹饪”的所有产品,然后寻找其他有“面条”的产品,最后是“健康”。

显示的产品必须按顺序显示:首先显示标签列中包含“烹饪”的所有产品,然后显示“面条”,最后显示“健康”。重要的是,产品不必重复。

这是我希望得到的顺序:ID: 25, 25, 40, 43, 46

这是数据库

ID 标签 姓名
23 烹饪,面条,健康 面条 热白胡椒
25 烹饪,面条,健康 面条的肥皂
35 烹饪,面条,健康 胡萝卜面条
40 食物,面条,番茄酱 番茄酱新面条
43 苹果,厨师,健康 苹果加糖
46 香蕉, 厨师, 健康 香蕉加糖

谢谢您的帮助!!

标签: sqlcsvtags

解决方案


您存储数据的方式使事情变得不必要地次优。您不应该将多个字符串存储在单个列中;相反,应该有另一个表来存储产品和标签之间的关系,每个元组应该在单独的行上。

对于您当前的设计,您可以执行以下操作:

select t.*
from mytable t
where 
    ',' || tags || ',' like '%,cooking,%'
    or ',' || tags || ',' like '%,noodles,%'
    or ',' || tags || ',' like '%,healthy,%'
order by 
    case
        when ',' || tags || ',' like '%,cooking,%' then 1
        when ',' || tags || ',' like '%,noddles,%' then 2
        else 3
    end,
    id

这使用标准的字符串连接运算符||:您可能需要将其适应您的实际数据库。

一些数据库具有搜索 CSV 列表的内置功能。例如,如果您正在运行 MySQL:

select t.*
from mytable t
where 
    find_in_set('cooking', tags)
    or find_in_set('noodles', tags)
    or find_in_set('healthy', tags)
order by 
    case
        when find_in_set('cooking', tags) then 1
        when find_in_set('noodles', tags) then 2
        else 3
    end,
    id

推荐阅读