我有一个“更新”表,可以包含重复的描述,我想返回重复项及其计数,所以我创建了这个查询:
SELECT description, count(description) AS count
FROM updates INNER JOIN participations ON participations.status_id = updates.id
INNER JOIN customer ON customer.id = participations.customer_id
INNER JOIN garages ON garages.id = customer.garage_id
WHERE (updates.created_at >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH))
GROUP BY description
ORDER BY count desc
返回的计数并不是我所期待的。我相信原因是因为许多客户可以共享更新,因此我会因为表中的实际重复而得到重复,并且因为多次返回相同的更新记录。如何修复查询以使其仅计算更新表中的实际重复描述字段。感谢
答案 0 :(得分:3)
我认为您可以删除与参与和车库的连接,因为您既不是将它们用作过滤器,也不是在选择中使用它们的字段。但如果你确实使用它们,那么它应该做这样的事情:
SELECT description, count(description) AS count
FROM updates
WHERE (updates.created_at >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH))
AND EXISTS (SELECT 1 FROM participations INNER JOIN customer ON customer.id = participations.customer_id INNER JOIN garages ON garages.id = customer.garage_id WHERE participations.status_id = updates.id)
GROUP BY description
ORDER BY count desc
答案 1 :(得分:1)
根据mysql manual,您可以将HAVING
子句与GROUP BY
生成的字段一起使用:
HAVING子句可以引用SELECT列表或外部子查询中的select_expr中指定的任何列或别名,以及聚合函数。但是,SQL标准要求HAVING必须仅引用GROUP BY子句中的列或聚合函数中使用的列。
例如:
SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;
因此您可以使用以下查询:
SELECT description, count(description) AS count
FROM updates INNER JOIN participations ON participations.status_id = updates.id
INNER JOIN customer ON customer.id = participations.customer_id
INNER JOIN garages ON garages.id = customer.garage_id
WHERE (updates.created_at >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH))
GROUP BY description
HAVING count > 1
ORDER BY count desc
答案 2 :(得分:0)
如果我理解正确且描述用于多个客户 / garages,那么您需要按所有唯一性标识符进行分组,而不仅仅是description
:
SELECT description, customer.id, garages.id, count(*) AS count
FROM updates
JOIN participations ON participations.status_id = updates.id
JOIN customer ON customer.id = participations.customer_id
JOIN garages ON garages.id = customer.garage_id
WHERE (updates.created_at >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH))
GROUP BY description, customer.id, garages.id
HAVING count > 1
ORDER BY count desc