为什么引入日期参数​​会弄乱我的查询? mySQL 中的 3 个表加入

why introducing date parameter messes up my query? 3 tables JOIN in mySQL

编写一份报告 return 3 列

  1. 所有简单产品列表
  2. 每种产品的当前库存水平
  3. 每种产品在指定时期内的销售数量。如果没有销售额,则显示为零。
sku       | qty | sold qty    
product 1 | 5   | 15    
product 2 | 7   | 0    
product 3 | 0   | 15    
product 4 | 0   | 0

代码在未指定日期期间时按预期工作。但是,这给了我完整的销售历史记录。我想查看上个月、上季度、上年的销售历史记录。

当使用上面的行指定时间段时,它会跳过在指定时间段内没有销售的 SKU。

sku       | qty | sold qty    
product 1 | 5   | 15    
product 3 | 0   | 15

我想查看所有 SKU,包括销售额为零的 SKU。

SELECT 
    p.sku,
    FORMAT(s.qty, 0) AS qty,
    IFNULL(FORMAT(SUM(o.qty_invoiced), 0), 0) AS 'sold qty'
FROM
    mage_catalog_product_entity AS p
        LEFT JOIN
    mage_cataloginventory_stock_item AS s ON p.entity_id = s.product_id
        LEFT JOIN
    mage_sales_flat_order_item AS o ON p.entity_id = o.product_id
WHERE
    p.type_id = 'simple' 
       AND o.created_at BETWEEN '2018-11-01 00:00:01' AND '2019-01-31 23:59:59'
GROUP BY p.sku
ORDER BY SUM(o.qty_invoiced) DESC;

我想在第 1 列中查看所有 SKU,包括销售额为零的那些。它在查看整个销售历史记录而不指定日期期间时会这样做。不确定在组合中添加日期期间如何改变结果。

您在 WHERE 子句中对 o.created_at 的条件是将 LEFT JOINmage_sales_flat_order_item 转换为 INNER JOIN。要解决这个问题,移动

AND o.created_at BETWEEN '2018-11-01 00:00:01' AND '2019-01-31 23:59:59'

WHERE 子句中进入 ON 子句中 LEFT JOINmage_sales_flat_order_item

最简单的方法是将条件移动到on子句:

SELECT p.sku,
       FORMAT(SUM(s.qty), 0) AS qty,
       COALESCE(FORMAT(SUM(o.qty_invoiced), 0), 0) AS `sold qty`
FROM mage_catalog_product_entity p LEFT JOIN
     mage_cataloginventory_stock_item s
     ON p.entity_id = s.product_id LEFT JOIN
     mage_sales_flat_order_item o
     ON p.entity_id = o.product_id AND
        o.created_at >= '2018-11-01' AND
        o.created_at < '2019-02-01'
WHERE p.type_id = 'simple' 
GROUP BY p.sku;

关键的变化是将日期条件移动到 ON 子句中。这样,它就不会将外部连接变成内部连接。

其他变化:

  • 注意日期算法的变化。不要将 between 与日期一起使用。在这种情况下,它只是一团糟,一天中错过了两秒钟——我想这不是故意的。
  • 我更喜欢 COALESCE() 而不是 IFNULL() 因为 COALESCE() 是标准 SQL.
  • s.qty 需要做一些事情。将其包含在 GROUP BY 中或使用聚合函数。我选择了后者,不知道数据长什么样