MySQL加入并排除count = 0的行

时间:2014-06-25 13:06:38

标签: php mysql

我有以下简单的查询,它是垃圾收集脚本的一部分。该脚本应该删除未使用的购物车。购物车在超过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的那些购物车,我无法找出原因。有线索吗?

3 个答案:

答案 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;