[英]MySQL Join and excluding rows with count=0
I have the following straightforward query which is part of a garbage collection script. 我有以下简单查询,它是垃圾回收脚本的一部分。 The script is supposed to delete unused shopping carts.
该脚本应删除未使用的购物车。 A cart is unused when it was updated more than 24 hours ago and is not attached to an order or a user.
超过24小时前更新的购物车尚未使用,并且未附加到订单或用户。
$query = "SELECT comm_cart.id AS `cart_id`, (" . time() . " - comm_cart.update_date) AS `diff`, COUNT(comm_orders.cart_id) AS `c1`, COUNT(comm_users.cart_id) AS `c2` " .
"FROM `comm_cart` " .
"LEFT JOIN `comm_orders` ON comm_cart.id=comm_orders.cart_id " .
"LEFT JOIN `comm_users` ON comm_cart.id=comm_users.cart_id " .
"GROUP BY comm_cart.id ";
"HAVING `diff`>86400 AND `c1`=0 AND `c2`=0";
The query finds too many carts: it also tags the ones that have a c1>0 or c2>0 and I can't figure out why. 该查询找到了太多的购物车:它还标记了c1> 0或c2> 0的购物车,我不知道为什么。 Any clues?
有什么线索吗?
I suspect that you are joining along two different dimensions. 我怀疑您正在沿着两个不同的维度加入。 The easy fix is to use
distinct
: 简单的解决方法是使用
distinct
:
SELECT comm_cart.id AS `cart_id`, (" . time() . " - comm_cart.update_date) AS `diff`,
COUNT(DISTINCT comm_orders.cart_id) AS `c1`, COUNT(DISTINCT comm_users.cart_id) AS `c2` " .
The better solution would be to use not exists
for these two conditions: 更好的解决方案是针对这两个条件使用
not exists
:
FROM comm_carts cc
WHERE not exists (select 1 from comm_orders co where cc.id = co.cart_id )
not exists (select 1 from comm_users cu where cc.id = cu.cart_id )
You don't even need the group by, an isnull condition in the where would work wonders, of course I suggest using Gordon's suggestion of the not exists, but if you want the minimum change this would be is. 您甚至不需要在可能起作用的奇迹所在的情况下进行分组,当然,我建议使用Gordon关于不存在的建议,但是如果您希望进行最小的更改,那就是。
SELECT
comm_cart.id AS `cart_id`,
(UNIX_TIMESTAMP() - comm_cart.update_date) AS `diff`
FROM `comm_cart`
LEFT JOIN `comm_orders`
ON comm_cart.id=comm_orders.cart_id
LEFT JOIN `comm_users`
ON comm_cart.id=comm_users.cart_id
WHERE
comm_orders.cart_id IS NULL
AND
comm_users.cart_id IS NULL
Oh, and I've used UNIX_TIMESTAMP()
instead of the PHP time function, same effect, but this avoids mixing PHP and SQL. 哦,我已经使用
UNIX_TIMESTAMP()
代替了PHP时间函数,效果相同,但是这避免了将PHP和SQL混合使用。
if you only want to get data with c1=0 and c2=0 then you need to write a where condition instead of having before group by, 如果您只想获取c1 = 0和c2 = 0的数据,则需要编写一个where条件,而不是使用group by之前,
$query = "SELECT comm_cart.id AS `cart_id`, (" . time() . " - comm_cart.update_date) AS `diff`, COUNT(comm_orders.cart_id) AS `c1`, COUNT(comm_users.cart_id) AS `c2` " .
"FROM `comm_cart` " .
"LEFT JOIN `comm_orders` ON comm_cart.id=comm_orders.cart_id " .
"LEFT JOIN `comm_users` ON comm_cart.id=comm_users.cart_id " .
" where c1=0 and c2 =0 and diff >86400 GROUP BY comm_cart.id;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.