如何在SQL中优化列表中的搜索

时间:2015-02-26 12:43:25

标签: mysql sql

我必须在Mysql中创建一个SQL查询来搜索列中的字符串列表(例如:1,2,3)(例如:list_id),它也有字符串值列表(1,2,3) 。

有关详细信息,my_table为

+-----------+----------+
| id        | list_id  |
+-----------+----------+
| 1         | 29       |
| 2         | 30       |
| 3         | 31       |
| 4         | 4,5,6,7  |
| 5         | 8,9,10,11| 
| 6         | 4,5,8,9  |
| 7         | 1,2,3,6  |
+-----------+----------+

搜索值是1,5,8,我需要得到列的list_id在列表中有1或5或8。因此,结果将是:

+-----------+----------+
| id        | list_id  |
+-----------+----------+
| 4         | 4,5,6,7  |
| 5         | 8,9,10,11|
| 6         | 4,5,8,9  |
| 7         | 1,2,3,6  |
+-----------+----------+

我的查询字符串是:

SELECT * FROM my_table
WHERE list_id LIKE '%,1,%'
   OR list_id LIKE '1,%'
   OR list_id LIKE '%,1'
   OR list_id LIKE '%,5,%'
   OR list_id LIKE '5,%'
   OR list_id LIKE '%,5'
   OR list_id LIKE '%,8,%'
   OR list_id LIKE '8,%'
   OR list_id LIKE '%,8'

匹配正确我想要的。但是,查询的长度与列表的长度成比例。

在这种情况下,REGEXP是否优于LIKE? 有没有人有更好的解决方案?

3 个答案:

答案 0 :(得分:1)

您可以尝试将逗号连接到您的字段(或使用MySQL中的SET或创建更好的数据库结构 - 您可以在其中连接存储相关数据的表)。

SELECT * FROM yourtable WHERE CONCAT(',', fieldname, ',') like '%,1,%';

答案 1 :(得分:0)

是的,正则表达式适用于此。您可以这样做:

SELECT * FROM junk
 WHERE CONCAT(',', list_id, ',') REGEXP CONCAT(',(', REPLACE('1,3,8',',','|'), '),');

结果:

ID | LIST_ID
5  | 8,9,10,11
6  | 4,5,8,9
7  | 1,2,3,6

Please see SQL Fiddle demo here.

我们将查询列表1,3,8转换为交替组1|3|8。您可以在应用程序代码中执行此操作,以避免使用上面的REPLACE()函数。

更新道歉,我错误地使用1,3,8作为查询参数而不是1,5,8。但它应该仍然有效。

答案 2 :(得分:0)

我强烈建议你改变数据库的设计(我假设你对它有一些控制或影响)。

您应该使id列不唯一,然后list_id列应包含单个值。然后,您可以按如下方式搜索:

SELECT id WHERE list_id IN (1,5,8)

如果它是一个大表并且有很多list_id值,请在list_id列上放一个索引。

如果您需要以逗号分隔列表输出,那么您将需要使用与GROUP BY的聚合连接函数(例如,MySQL中的GROUP_CONCAT())。

如果您无法更改架构的设计,请使用此处的其他建议之一。