Mysql SQL在1天前和1周前的行之间存在差异

Mysql SQL在1天前和1周前的行之间存在差异,mysql,sql,join,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

我在表单中有一个名为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个连接时,有三个连接


有更好的方法吗?

我觉得你的问题很好。SQL的挑战之一是,当您解决像这样的实际问题时,它会变得冗长和重复。我发现使用我称之为club sandwich格式的东西很有帮助——它使结构化查询语言中的结构可见

看看查询是如何由一堆不同的东西组成的,比如三明治

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


有一件小事需要注意。查询中的内部联接将用于抑制一天前或一周前没有库存的项目的结果集中的行。请改为尝试左连接。

您可以使用条件聚合: 您只需使用LEFT JOIN和过去每天的一个JOIN来表示这一点:

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;

此外,MySQL不允许在FROM子句中对视图进行子查询,因此,您的查询对视图不起作用。

检查哪一天是一周的第一天-我不确定这是否是问题所在,但当我们谈论本周时,我会想到这一点periods@BogdanBogdanov理想情况下,我会确保它不包括周末,但这完全是另一个问题!如果你知道一个解决方案,这将是惊人的好格式-非常容易阅读的查询都是关于什么。
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;