首页 > 解决方案 > mysql find_in_set 字符串开头

问题描述

我需要以逗号分隔值中的给定字符串开头搜索值。
例如,
我的专栏中有“1_2_3_4_5_6、1_2_3_4_5_8、1_2_3_6_5_8”。我可以使用搜索具有确切值的行
select * from table where find_in_set('1_2_3_4_5_6',column)

但是如果给出了字符串的起始部分,如何搜索?像这样的东西:
select * from table where find_in_set('1_2_3%',column)

标签: phpmysqlmysqli

解决方案


如果我理解正确(我仍然不确定我是否理解),您可以使用:

SELECT * FROM table WHERE column LIKE '%1_2_3%';

这将为您提供值如下的列:

1_2_3_4_5_5
1_4_5_, 1_2_3_4_5_, 6_7

等等。

但是您应该真正规范化您的表格。这对于良好的查询很重要,性能方面也很重要。

根据@Xatenev 的建议,如果您真的只喜欢每个匹配行的值和行,那么这将不会很好并且会产生很多开销。这是我将执行的步骤:

  1. 将所有 CSV 列拆分为多行(这是一个 hack 和性能杀手,我找到了一些可行的解决方案但没有对其进行测试,请参见此处):伪代码:(SELECT ID, SPLIT(',', column) AS entries FROM table不工作)
  2. 过滤新的虚拟表以仅选择与前缀 ( SELECT * FROM virtual_table WHERE find_in_set("1_2_3%, entries) ORDER BY ID)匹配的行
  3. 将匹配项连接entries回每个ID. 例如SELECT ID, GROUP_CONCAT(entries SEPARATOR ', ') FROM filtered_table GROUP BY ID
  4. 做一点事

未知部分是拆分为多行的开头。有很多可能的解决方案都有自己的缺点或优点。请注意,这将始终(无论选择何种方法)会消耗大量性能。

附加节点:

在你的情况下可能是冒险,你让每一行匹配你的搜索字符串,就像我的第一个例子一样,并在内存中过滤它们。这可能比在 MYSQL 中执行此操作要快。


推荐阅读