我试图在表'apst_mailings'上运行查询,存储我们发送给订阅者的每个时事通讯的内容.每当我们尝试将电子邮件发送给个人时,我们在apst_mailings_accuses中插入一行,报告发送的时间和状态以及新邮件的ID.我想列出新闻通讯并计算每个发送和成功发送的总数.
SELECT m.id AS code_mailing,
COUNT(a.adh_code) AS num, COUNT(b.adh_code) AS succes
FROM apst_mailings AS m
LEFT OUTER JOIN apst_mailings_accuses AS a
ON a.id_mailing = m.id
LEFT OUTER JOIN apst_mailings_accuses AS b
ON b.id_mailing = m.id
AND b.etat = 'succes'
GROUP BY m.id
Run Code Online (Sandbox Code Playgroud)
它只是永远挂起服务器.我已尝试在分离的查询中的每个连接,它没有问题的工作:
// Counts the email sent per mailing
SELECT m.id AS code_mailing,
COUNT(a.adh_code) AS num
FROM apst_mailings AS m
LEFT OUTER JOIN apst_mailings_accuses AS a
ON a.id_mailing = m.id
GROUP BY m.id
SELECT m.id AS code_mailing,
COUNT(b.adh_code) AS succes
FROM apst_mailings AS m
LEFT OUTER JOIN apst_mailings_accuses AS b
ON b.id_mailing = m.id
AND b.etat = 'succes'
GROUP BY m.id
Run Code Online (Sandbox Code Playgroud)
我可以分割我的查询,但它不起作用的原因真的困扰我.有人可以解释一下吗?
谢谢!
通过使用单个连接并使用SUM执行条件计数,您可以以更简单的方式获得所需的内容.
SELECT
m.id AS code_mailing,
COUNT(a.adh_code) AS num,
SUM(a.etat = 'succes') AS succes
FROM apst_mailings AS m
LEFT OUTER JOIN apst_mailings_accuses AS a
ON a.id_mailing = m.id
GROUP BY m.id
Run Code Online (Sandbox Code Playgroud)
但是,为什么您的查询不工作的原因是因为要加入所有的子查询行一个与所有的子查询匹配的行b在一个巨大的交叉连接.这可能会生成一个巨大的临时结果集,这可能是为什么查询需要永远终止的原因.即使它确实终止了,你的计数也会完全消失 - 它们将是两个计数的产物.
首先解决它GROUP BY.然后JOIN将结果发送到主表.
SELECT
m.id AS code_mailing,
IFNULL(a.num, 0) AS num,
IFNULL(b.succes, 0) AS succes
FROM apst_mailings AS m
LEFT OUTER JOIN (
SELECT id_mailing, COUNT(adh_code) AS num
FROM apst_mailings_accuses
GROUP BY id_mailing
) a
ON a.id_mailing = m.id
LEFT OUTER JOIN (
SELECT id_mailing, COUNT(adh_code) AS succes
FROM apst_mailings_accuses
WHERE etat = 'succes'
GROUP BY id_mailing
) b
ON b.id_mailing = m.id
Run Code Online (Sandbox Code Playgroud)