行在1天和1周前的SQL差异

时间:2015-09-05 13:04:41

标签: mysql sql join

我有一个表格(名为stock_level),格式为

product_code | quantity | date

我想创建一个表单视图

product_code | date | quantity today - quantity 1 week ago | quantity today - quantity 1 day ago

到目前为止,我的选择为:

SELECT d.product_code, d.date, d.day_change, w.week_change
FROM (SELECT p1.date, p1.product_code, p1.quantity - p2.quantity as day_change
FROM stock_level p1
INNER JOIN stock_level p2
    ON p1.product_code = p2.product_code
    AND p2.date = p1.date - INTERVAL 1 DAY) d
INNER JOIN
(SELECT p1.date, p1.product_code, p1.quantity - p2.quantity as week_change
FROM stock_level p1
INNER JOIN stock_level p2
    ON p1.product_code = p2.product_code
    AND p2.date = p1.date - INTERVAL 7 DAY) w
ON d.product_code = w.product_code
AND d.date = w.date
ORDER BY d.date desc

虽然我正在做的事情似乎有效,但感觉效率并不高(例如,有三个联接,例如逻辑上它应该需要2个)

我有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

您可以使用条件聚合执行此操作: 您应该在过去的每一天使用mysql> show variables like 'char%'; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | latin1 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+ 8 rows in set (0.00 sec) mysql> show variables like 'coll%'; +----------------------+-------------------+ | Variable_name | Value | +----------------------+-------------------+ | collation_connection | utf8_general_ci | | collation_database | latin1_swedish_ci | | collation_server | latin1_swedish_ci | +----------------------+-------------------+ 3 rows in set (0.00 sec) 和单个联接来表达这一点:

LEFT JOIN

此外,MySQL不允许视图的SELECT slnow.product_code, slnow.date, (slnow.quantity - sl1.quantity) as day_change, (slnow.quantity - sl7.quantity) as week_change FROM stock_level slnow LEFT JOIN slock_level sl1 ON slnow.product_code = sl1.product_code AND sl1.date = slnow.date - interval 1 day LEFT JOIN stock_level sl7 ON slnow.product_code = sl7.product_code AND sl7.date = slnow.date - interval 7 day ORDER BY slnow.date DESC; 子句中的子查询,因此您的查询将不适用于视图。

答案 1 :(得分:2)

您的查询对我来说很好。 SQL的一个挑战是,当你解决像这样的现实问题时,它会变得冗长和重复。我觉得使用我称之为“三明治”格式的东西很有帮助 - 它使结构化查询语言中的结构可见。

SELECT d.product_code, d.date, d.day_change, w.week_change
  FROM (
           SELECT p1.date, p1.product_code, 
                  p1.quantity - p2.quantity as day_change
             FROM stock_level p1
            INNER JOIN stock_level p2 ON p1.product_code = p2.product_code
                                      AND p2.date = p1.date - INTERVAL 1 DAY
            ) d
 INNER JOIN (
            SELECT p1.date, p1.product_code, 
                   p1.quantity - p2.quantity as week_change
             FROM stock_level p1
             INNER JOIN stock_level p2 ON p1.product_code = p2.product_code
                                      AND p2.date = p1.date - INTERVAL 7 DAY
       ) w ON d.product_code = w.product_code
          AND d.date = w.date
 ORDER BY d.date desc

查看查询是如何堆叠的不同的东西,如三明治?

这对下一个处理查询的人有好处。只需一点视觉模式识别,她就能识别出任何其他语言的方法调用。

有一件小事需要注意。查询中的INNER JOIN将用于取消结果集中的行,这些行是针对一天前或一周前没有库存的项目。请改为LEFT JOIN