服务器更新后HAVING子句不起作用

时间:2015-02-10 11:43:25

标签: mysql having-clause

我们刚刚将mysql版本从5.0.51升级到5.6.22,我刚刚注意到我的一个查询不再正常工作。

SELECT
  p.id AS product_id,
  p.code,
  p.description,
  p.unitofmeasure,
  p.costprice,
  p.packsize,
  vc.rateinpercent,
  CASE
    WHEN Sum(sales.qty) IS NULL THEN 0
    ELSE Sum(sales.qty)
  END AS sold,
  CASE
    WHEN stock.stocklevel IS NULL THEN 0
    ELSE stock.stocklevel
  END AS stocklevel,
  sum(sales.qty) - stock.stocklevel AS diff,
  CEIL((sum(sales.qty) - stock.stocklevel) / p.packsize) AS amt
FROM   products p
LEFT JOIN 
  ( SELECT 
      col.product_id,
      col.quantity AS qty
    FROM customerorderlines col
    LEFT JOIN customerorders co
    ON co.id = col.customerorder_id
    WHERE co.orderdate >= '2014-12-01 00:00:00'
      AND co.orderdate <= '2015-02-09 23:59:59'
      AND co.location_id IN (1,2,3,7)
  ) sales
  ON sales.product_id = p.id
LEFT JOIN 
    ( SELECT 
        product_id,
        location_id,
        Sum(stocklevel) AS stocklevel
      FROM stock
      WHERE location_id IN (1,2,3,7)
      GROUP BY product_id
    ) stock
  ON stock.product_id = p.id
LEFT JOIN vatcodes vc 
  ON vc.id = p.purchasevatcode_id
WHERE p.supplier_id IN (137)
  AND p.currentstatus_v = 1
GROUP BY p.id
HAVING sold > stocklevel
ORDER BY sold DESC

在旧服务器上,HAVING子句过滤掉所有带有minus的结果,给出如下结果:

Old Result

相反,我在新服务器上得到以下结果:

New Result

基本上,它会过滤掉一些的否定结果,但不是全部。 (数据集有几天了,这就是为什么'冻结凝胶喷雾'数量和销售量和库存数量略有不同)

后见之明是一件很棒的事情,但我没想到服务器更新之间的查询会有任何重大变化,所以我不关心测试或检查任何东西。幸运的是,这只是两个或三个使用HAVING的查询之一,所以如果我必须重写几个查询,那就这样吧。关于为什么会这样的任何想法?如果它根本不起作用,那么公平,但只是部分工作?

提前感谢任何见解,

[R

1 个答案:

答案 0 :(得分:1)

我认为你已经在查询上尝试过EXPLAIN来找出它在做什么?

尝试使用基础字段名称使计算的字段名称唯一,这样您就可以确定要过滤的内容。当计算字段与底层物理字段具有相同的名称时,我看到了一些棘手的结果。

让子查询返回相同格式的结果(即两者相加/分组)有助于查看正在发生的事情。

我没有测试过这个查询,但它可能有所帮助。如果您发布表结构以及可能显示错误的一些虚假数据,那将有助于诊断

SELECT 
    p.id AS product_id,
    p.code,
    p.description,
    p.unitofmeasure,
    p.costprice,
    p.packsize,
    vc.rateinpercent,
    sales.totalSold,
    stock.totalStock,
    sales.totalSold - stock.totalStock AS diff,
    CEIL((sales.totalSold - stock.totalStock) / p.packsize) AS amt
FROM products p
LEFT JOIN (
    SELECT
        col.product_id,
        IFNULL( SUM(col.quantity), 0) AS totalSold
    FROM    customerorderlines col
    LEFT JOIN customerorders co
    ON      co.id = col.customerorder_id
    WHERE   co.orderdate >= '2014-12-01 00:00:00'
    AND     co.orderdate <= '2015-02-09 23:59:59'
    AND     co.location_id IN (1,2,3,7)
    GROUP   BY product_id
) sales
ON  sales.product_id = p.id
LEFT JOIN (
    SELECT
        product_id,
        IFNULL( SUM(stocklevel), 0) AS totalStock
    FROM    stock
    WHERE   location_id IN (1,2,3,7)
    GROUP   BY product_id
) stock
ON  stock.product_id = p.id
LEFT JOIN vatcodes vc
ON  vc.id = p.purchasevatcode_id
WHERE   p.supplier_id IN (137)
AND     p.currentstatus_v = 1
GROUP   BY p.id
HAVING  totalSold > totalStock
ORDER   BY totalSold DESC