我有以下简单的查询,它是垃圾收集脚本的一部分。该脚本应该删除未使用的购物车。购物车在超过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";
查询找到了太多的购物车:它还标记了c1> 0或c2> 0的那些购物车,我无法找出原因。有线索吗?
答案 0 :(得分:1)
我怀疑你是在加入两个不同的维度。简单的解决方法是使用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` " .
更好的解决方案是在这两个条件下使用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 )
答案 1 :(得分:1)
你甚至不需要小组,在哪里可以创造奇迹,当然我建议使用戈登的建议不存在,但如果你想要最小的改变,那就是。
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
哦,我使用UNIX_TIMESTAMP()
而不是PHP时间函数,效果相同,但这样可以避免混合使用PHP和SQL。
答案 2 :(得分:0)
如果你只想获得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;