【问题标题】:mysql search keywords in string tablemysql在字符串表中搜索关键字
【发布时间】:2014-08-05 18:39:12
【问题描述】:

我在产品表中有一个 catID 列,它包含类别 ID 作为字符串,

类似'142,156,146,143'的东西

我有一个查询 '?catID=156,141,120'

我想搜索 catID 列中的每个 id。

我使用这个查询:

SELECT * FROM product WHERE catID REGEXP '156|141|120'

此代码返回在 catID 列中具有任何 id 的产品,但我想返回具有所有 id 的产品,

所以,我正在寻找 REGEXP 中的运算符,但我找不到。

我想使用 REGEXP 或类似的功能提供一个查询来查找产品,我不想使用

catID LIKE '156' AND catID LIKE '141' ....

如果可能的话。

编辑:我不想再执行一次函数,因为查询可能有 100+ id,所以编写代码更加困难,

【问题讨论】:

  • IN 子句是否不满足要求?
  • 否,IN 子句返回具有任何 id 的行,我想要返回具有所有 id 的行。
  • 那么catID 在每一行中不是唯一的吗?

标签: mysql regex search words


【解决方案1】:

您需要为每个类别 id 参数使用 find_in_set() 以查找集合中的值,如果您可以更改架构,然后通过另一个联结表来保存从该表到类别的关系,对其进行规范化表

select * from 
product 
where 
find_in_set('142',catID ) > 0

对于像find_in_set('161,168,234,678',preferred_location ) > 0 这样的多个值,不可能这样做,您必须为每个位置ID 执行类似

select * from 
product 
where 
find_in_set('142',catID ) > 0
and find_in_set('156',catID ) > 0
and find_in_set('146',catID ) > 0
and find_in_set('143',catID ) > 0 ... for more

Database normalization

find_in_set

示例架构

表格

  • 产品(id、其他列)
  • 类别(id、其他列)
  • Product_categories (id,product_id,category_id)

Product_categories 是一个联结表,每个产品将保存 product_id 和一个 category_id,因此每个产品一次都与单个类别和单个产品有关系

例如

产品

id  name

1  product 1
2  product 2

类别

id  name

142  category 1
156  category 2
146  category 3
143  category 4

产品类别

id  product_id  category_id
1     1          142  
2     1          156  
3     1          146  
4     1          143  

现在您可以使用 in() 加入这些表并进行如下查询,并且 count 应该等于作为参数提供的类别 ID 的数量

select p.* from
Products p
join Product_categories pc on (p.id = pc.product_id)
where pc.category_id in(142,156,146,143)
group by p.id
having count(distinct pc.category_id) = 4

Sample Demo

或者,如果您不能将提供的类别 ID 计为参数,您可以通过以下查询来完成此操作

select p.* from
Products p
join Product_categories pc on (p.id = pc.product_id)
where pc.category_id in(142,156,146,143)
group by p.id
having count(distinct pc.category_id) = 
ROUND (   
        (
            LENGTH('142,156,146,143')
            - LENGTH( REPLACE ( '142,156,146,143', ",", "") ) 
        ) / LENGTH(",")        
    ) + 1

Sample Demo 2

【讨论】:

  • 是的,我知道我可以通过多次执行 IN 或 find_in_set() 函数来做到这一点,但如果可能的话,我想只用一次执行来做到这一点。有没有其他方法 REGEXP或类似的东西?
  • @sanchez23 是的,如果你通过对其应用一些规范化来正确组织你的结构,如果你不能改变你的架构,那么我想没有其他方法,或者如果是这样,那么我想没有其他方法用户定义的函数或其他东西会非常复杂
  • 是的,我可以规范化这个数据库,你有建议或例子,我怎样才能规范化这个数据库?
  • @sanchez23 看到我更新的答案希望它有意义
猜你喜欢
  • 2016-06-02
  • 2014-12-08
  • 2019-03-13
  • 1970-01-01
  • 1970-01-01
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多