【问题标题】:Searching multiple values in a Comma-Separated MySQL column in a single query在单个查询中搜索逗号分隔的 MySQL 列中的多个值
【发布时间】:2013-10-14 06:13:52
【问题描述】:

完全了解表列中的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 的情况下进行查询?

【问题讨论】:

标签: php mysql sql


【解决方案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

【讨论】:

    【解决方案2】:

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

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

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

    表“Subjects2Lists”(多对多) 主题ID(索引)| 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 
    

    【讨论】:

    • 我已经在我的问题上发布了这个事实,Marcel,但感谢您的努力。
    • 嗯...对不起。认为对其他人来说可能很好,以避免问题对于您的特定问题,我将创建一个以邮件列表的 id 作为参数的存储过程。因此,您可以遍历 id 并创建一个完整的语句并执行它。
    • 是的,但在这种情况下,我宁愿在 PHP 中执行此操作。不过,我将规范我的表结构,因为我计划进行一次重大更新,但我认为提出这个问题值得一试。
    猜你喜欢
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-29
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多