在单个查询中搜索逗号分隔的MySQL列中的多个值

时间:2013-10-14 06:13:53

标签: php mysql sql

我在表列中完全了解 how bad it is to have Delimited Lists,而不是将数据规范化为多个表。

虽然我确实有一个多年前设计的表结构我很快会重新设计
简化,它看起来像这样:

Table: Newsletters
+------------+---------------+
| subject    | mailing_lists |
+------------+---------------+
| A Test     | 1,2           |
| More Tests | 2,3           |
+------------+---------------+ 

如果您愿意,可以在此SQLFiddle中看到它。

最近,我向用户提供了编写分隔邮件列表ID列表 (如1,3)的选项,作为选择要显示的新闻简报的功能在一个视图中 (例如,只显示发送到ID为1或3的列表的简报)

所以:一个表列,其中包含id的分隔列表,以及作为输入的分隔ID。

如果表格被标准化,这显然会容易得多。

所以,我在PHP中解决了这个问题,通过对输入ID进行爆炸并迭代它们来创建类似fiddle mentioned above中的查询,如下所示:

SELECT * FROM `newsletters`
  WHERE FIND_IN_SET("1", `mailing_lists`) > 0
     OR FIND_IN_SET("3", `mailing_lists`) > 0

此查询完美地获取了我想要获取的数据,但我只能以编程方式创建它,因为我必须为我的分隔列表中的每个id添加一个新条件。

问题是:出于纯粹的好奇心:有没有办法避免PHP中的循环,并在不将代码中的ID分开的情况下进行查询?

2 个答案:

答案 0 :(得分:1)

rakeshjain非常有用的帖子之后,我设法将我的查询转换为:

SELECT * FROM (SELECT *,
               `mailing_lists` REGEXP REPLACE("1,3", ',', '(\\,|$)|')
                  as haslists
               FROM `newsletters` B) A
  WHERE A.haslists = 1

在上文中,我假设“1,3”是用户提供的值 这是解决的小提琴:http://sqlfiddle.com/#!2/4621b0/19

谢谢rakeshjain

答案 1 :(得分:0)

是的,有办法避免循环。只需规范化您的数据库结构。

表“主题” subjectID(INT(11),auto_increment))| subject(varchar(255))

表“邮件列表” listID(INT(11),auto_increment)| LISTNAME

表“主题2列表”(多对多) subjectID(索引)| listID(索引)

因此,您可以通过执行简单的select / join语句来获取每个列表ID。

SELECT 
    list.listID, 
    names.listName 
FROM 
    Subject2Lists AS list 
LEFT JOIN 
    MailingLists AS names 
    ON (list.listID = names.listID) 
WHERE 
    subjectID = 1