【问题标题】:Updating multiple rows in MySQL without a loop在没有循环的情况下更新 MySQL 中的多行
【发布时间】:2012-08-02 20:53:36
【问题描述】:

我正在尝试为我创建的招聘网站编写电子邮件通知系统,目前正在考虑将一定数量的工作组合在一起,然后再向候选人发送电子邮件

我有一个表,我称之为candidate_to_job,其中包含candidate_id、job_id 和“通过电子邮件发送”的布尔值

我正在努力在发布新工作并发送电子邮件时更新该表。到目前为止,当发布新工作时,我运行以下命令:

SELECT     c2j.candidate_id, c2j.job_id, j.title 
FROM       " . DB_PREFIX . "candidate_to_job c2j 
LEFT JOIN  " . DB_PREFIX . "job j 
       ON  (j.job_id = c2j.job_id) 
WHERE      c2j.emailed = 0

然后通过 PHP 我将它们组合在一起,所以我有一个看起来像这样的数组:

$candidates = array(
    1 => array(1,2,3),
    2 => array(1,3),
    3 => array(4,5,6)
);

数组键是候选人 ID,值是作业 ID 数组

我想要使用该数组执行的操作 - 在发送电子邮件后 - 将通过电子邮件发送的 Candidate_to_job 表设置更新为 true,例如,对于 job_ids 1、2 和 3,candidate_id 1 将通过电子邮件设置为 true

有没有一种方法可以在一个查询中做到这一点?我看过 WHEN CASE 语句,但我认为这不适用于这种情况?我真的不想为每个候选人运行多个查询,因为可能有数千个!

【问题讨论】:

    标签: php mysql sql-update


    【解决方案1】:

    您可以为每个组运行一个UPDATE 查询,前提是该组可以共享相同的WHERE 条件和相同的更新值。

    UPDATE tbl SET value = TRUE WHERE id IN(1,2,3,4,5,6);
    UPDATE tbl SET value = FALSE WHERE id IN(7,8,9,10,11);
    

    如果条件足够简单,您也可以使用WHEN 子句甚至一些IF 子句。

    UPDATE tbl SET value = IF(id = 1) WHERE id IN(1,2);
    UPDATE tbl
        SET value = CASE
                        WHEN id IN (1,2,3,4,5,6) THEN TRUE
                        WHEN id IN (7,8,9,10,11) THEN FALSE
                        ELSE value
                    END
        WHERE id IN (1,2,3,4,5,6,7,8,9,10,11);
    

    可能有数千个WHEN 案例,构建/更改可能很麻烦,我会选择第一个选项:

    翻转旧的 key=>value 数组并保持所有 id 连接到一个值:

    foreach($list AS $id => $value) {
        $list2[$value][] = $id;
    }
    

    遍历 value=>keys 数组并构建 UPDATE 查询,可以一次批量更新所有键的值。

    【讨论】:

    • 我从没想过翻转数组。这是个好主意,我可以创建另一个数组,其中键作为作业 ID,然后将值作为候选 ID 数组 - 谢谢!
    • @ypercube 谢谢,我从没想过将INCASE 一起使用,SQL 语法对于固定流控制构造与预定义函数与预定义函数的确切含义不太直观。语句语法等。
    【解决方案2】:

    如果您在 PHP 中使用 mysqli 扩展而不是 mysql,您还可以编写多个语句,以 ';' 分隔并在一个查询中发送所有这些。这可能会导致代码比带有案例的复杂 UPDATE 稍微简单一些。

    我认为这不会比单个复杂的 UPDATE 语句花费更多的性能。

    【讨论】:

    • 根据经验,我总是“压缩”多个可以同时运行的语句,因为 PHP 和 MySQL 之间的通信协议通过 TCP 工作(它通常是本地数据库,但仍然是 TCP)和限制这些 TCP 通信与限制磁盘 IO 或任何其他昂贵的资源一样好。
    【解决方案3】:

    这就是你所追求的吗?您可以使用 from 和 where 进行连接,而无需在 PHP 中动态生成 SQL。

    UPDATE " . DB_PREFIX . "candidate_to_job c2j 
    SET emailed = 1
    FROM  " . DB_PREFIX . "job j 
    WHERE j.job_id = c2j.job_id and
          c2j.emailed = 0
    

    【讨论】:

    • 这不是和 UPDATE " . DB_PREFIX . "candidate_to_job SET emailed = 1 WHERE emailed = 0 一样吗?似乎没有关于更新哪些行的任何标准
    • 并且隐式过滤器应用于表作业上的任何匹配项。如果您根据第一个查询的结果创建了 PHP 数组,那么这应该可以工作。
    • 我想你可能误解了。每个工作都在工作表中,所以 WHERE j.job_id = c2j.job_id 总是正确的,不是吗?当职位发布并且匹配候选人职位标准时,这些条目将添加到 Candidate_to_job 表中
    • 您能否提供更多关于如何实现的上下文?在您的问题中,您声明您运行 SQL 然后使用 PHP 将结果粘贴到数组数组中。您如何确定数组中的内容?
    猜你喜欢
    • 2013-09-20
    • 1970-01-01
    • 2021-11-12
    • 2023-03-25
    • 1970-01-01
    • 2018-11-02
    • 2014-02-23
    • 2017-01-20
    • 1970-01-01
    相关资源
    最近更新 更多