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


Searching multiple values in a Comma-Separated MySQL column in a single query

完全意识到在表列中使用分隔列表而不是将数据规范化为多个表是多么糟糕。

虽然,我

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

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

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

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

So:一个表列,其中包含分隔的 id 列表,并将分隔的 id 作为输入。

如果对表进行规范化,这显然会容易得多。

因此,我在 PHP 中解决了这个问题,通过分解输入 id 并迭代它们以创建一个类似于上面提到的小提琴中的查询,如下所示:

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

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

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

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

是的,有一种方法可以避免循环。只需规范化数据库结构即可。

表"科目"主题 ID (INT(11), auto_increment)) |主题(瓦尔查尔(255))

表 "邮件列表"listID (INT(11), auto_increment) |列表名称

表"主题2列表"(多对多)主题 ID (索引) |列表 ID (索引)

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

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