2012-08-02 113 views
3

我正在尝试写一个电子邮件通知系统,用于我发布的求职招聘网站,并且目前正在将一定数量的作业分组在一起,然后将电子邮件发送给候选人在没有循环的情况下在MySQL中更新多行

我有我已经叫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 I组他们在一起,所以我有一个数组看起来像这样:

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

与数组键值为候选ID和作业ID数组的值

我想要使用该数组 - 电子邮件发送后 - 将更新candidate_to_job表设置通过电子邮件发送到true,例如candidate_id 1将通过电子邮件发送设置为true为job_ids 1,2和3

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

回答

3

如果该组可以共享相同的WHERE条件和相同的更新值,则可以为每个组运行一个UPDATE查询。

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情况下,可能是一个麻烦来构建/改变,我会跟第一个选项去:

翻转旧密钥=>值数组,并保持连接到所有IDS一个值:

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

迭代通过值=>键阵列和建立UPDATE的查询可以批量更新一次所有密钥的值。

+0

我甚至从来没有想过翻转阵列。这是一个好主意,我可以用键作为另一个数组作为工作id,然后是一个候选数组的值 - 谢谢! – Andy 2012-08-02 13:09:11

+0

@ypercube谢谢你,我从来没有想过在'CASE'中使用'IN',SQL语法不太直观,至于什么是固定的流控制结构还是什么?预定义函数与语句语法等。 – 2012-08-02 14:36:19

0

如果您在PHP中使用mysqli扩展而不是mysql,您还可以编写由';'分隔的多语句,并将其全部发送到一个查询中。这可能会导致比具有个案的复杂UPDATE更简单的代码。

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

+1

作为一个经验法则,我总是“压缩”多个语句,我可以一次运行,因为PHP和MySQL之间的通信协议通过TCP工作(它通常是本地数据库,但它是仍然是TCP),限制这些TCP通信与限制磁盘IO或任何其他昂贵的资源一样好。 – 2012-08-02 14:33:22

0

这是你在追求什么?您可以使用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 
+0

是不是就像UPDATE“。DB_PREFIX。”candidate_to_job SET电子邮件= 1在哪里电子邮件= 0?似乎没有任何标准要更新哪些行 – Andy 2012-08-02 13:06:04

+0

并且将隐式过滤器应用于表作业上的任何匹配。如果你从你的第一个查询的结果创建你的PHP数组,然后这应该工作。 – pyrospade 2012-08-02 13:39:39

+0

我想你可能误解了。每个工作都在工作表中,所以WHERE j.job_id = c2j.job_id总是会是真的不是吗?当作业发布时候,条目将被添加到candidate_to_job表中,并且该条目与候选人作业标准相匹配 – Andy 2012-08-02 13:47:49

相关问题