我有一个表格(名为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个)
我有更好的方法吗?
答案 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
。