HAVING子句影响结果

时间:2013-12-27 22:28:37

标签: mysql database left-join having

我有一个显示已售出和未售出产品的查询。

以下是正常运行的查询。

 SELECT p.product_id, 
    p.product_brand_id, 
    p.product_model_id, 
    p.product_subcategory_id,
    p.product_retail_price, 
    p.product_wholesale_price, 
    SUM(IFNULL(ps.product_quantity,0)) AS product_quantity_sold,
    SUM(IFNULL(ps.product_total_price,0)) AS total_price_sold, 
    pb.brand_name, 
    pm.model_name, 
    psub.subcategory_name
 FROM product p
 LEFT JOIN product_sold ps ON p.product_id = ps.product_id
 LEFT JOIN sales s ON ps.product_sales_id = s.sales_id
 JOIN product_brand pb ON pb.brand_id = p.product_brand_id
 JOIN product_model pm ON pm.model_id = p.product_model_id
 JOIN product_subcategory psub ON psub.subcategory_id = p.product_subcategory_id
 WHERE p.product_brand_id = $brand_id AND p.product_model_id = $model_id
   AND ( s.sales_id IS NULL
   OR ( s.sales_approved = '1' 
      AND s.sales_approved_time > '$start_timestamp'  
      AND s.sales_approved_time < '$end_timestamp'
      )
   )
   AND pb.brand_name NOT LIKE 'X%'
 GROUP BY p.product_id 
 ORDER BY product_quantity_sold DESC, pb.brand_name ASC, pm.model_name ASC

但是onced添加了必须过滤列表才显示

具有仅限销售的库存或产品的产品,具有以下查询:

 SELECT p.product_id, 
    p.product_brand_id, 
    p.product_model_id, 
    p.product_subcategory_id,
    p.product_retail_price, 
    p.product_wholesale_price, 
    SUM(IFNULL(ps.product_quantity,0)) AS product_quantity_sold,
    SUM(IFNULL(ps.product_total_price,0)) AS total_price_sold, 
    SUM(IFNULL(pq.product_quantity,0)) AS total_stock, 
    pb.brand_name, 
    pm.model_name, 
    psub.subcategory_name
 FROM product p
 LEFT JOIN product_sold ps ON p.product_id = ps.product_id
 LEFT JOIN sales s ON ps.product_sales_id = s.sales_id
 LEFT JOIN product_stock pq ON p.product_id = pq.product_id
 JOIN product_brand pb ON pb.brand_id = p.product_brand_id
 JOIN product_model pm ON pm.model_id = p.product_model_id
 JOIN product_subcategory psub ON psub.subcategory_id = p.product_subcategory_id
 WHERE p.product_brand_id = $brand_id AND p.product_model_id = $model_id
   AND ( s.sales_id IS NULL
   OR ( s.sales_approved = '1' 
      AND s.sales_approved_time > '$start_timestamp'  
      AND s.sales_approved_time < '$end_timestamp'
      )
   )
   AND pb.brand_name NOT LIKE 'X%'
 GROUP BY p.product_id 
 HAVING total_stock > 0 OR product_quantity_sold > 0
 ORDER BY product_quantity_sold DESC, pb.brand_name ASC, pm.model_name ASC

它有点奇怪,因为我在每个产品上得到不同的结果

product_quantity_sold

结果中的其他所有内容保持不变。

2 个答案:

答案 0 :(得分:2)

这与HAVING无关。

您的第二个查询与product_stock表连接,而第一个查询则不会。因此,每个相关股票条目都会重复每个预聚合记录。

例如,

product_id = 577出现在product_stock 8次,因此product_quantity_sold的值在第二个查询(184)中比在第一个查询(23)中大8倍。

答案 1 :(得分:0)

您的group by子句有缺陷 - 您需要列出所有非聚合列:

...
group by p.product_id, 
    p.product_brand_id, 
    p.product_model_id, 
    p.product_subcategory_id,
    p.product_retail_price, 
    p.product_wholesale_price, 
    pb.brand_name, 
    pm.model_name, 
    psub.subcategory_name 

在其他数据库中我知道,不这样做会导致错误,但在mysql中它是允许的,但具有特殊的非sql标准含义,为每个唯一的值组合返回一个随机行匹配行,聚合。