我是 MySQL 新手,我试图找到:
给定一天的最大值与前一天的最大值之间的差值。
我能够通过以下方式获得日期的最大值:
select max(`bundle_count`), `Production_date`
from `table`
group by `Production_date`
但我不知道如何使用 SQL 计算两个给定日期的最大值之间的差异。
我期待这样的输出
请帮我。
更新 1:这是我用于测试的小提琴http://sqlfiddle.com/#!2/818ad/2 。
更新 2:这是一个小提琴,http ://sqlfiddle.com/#!2 /3f78d/10,我根据桑迪的评论用于进一步完善/修复。
更新 3:由于某种原因,没有正确处理没有前一天的情况。我以为是。但是,我已经更新以确保它有效(有点麻烦 - 但它似乎是正确的。最后小提琴:http ://sqlfiddle.com/#!2/3f78d/45
我认为@Grijesh 在概念上通过输入数据的自联接为您提供了所需的主要内容(因此请确保您投票赞成他的答案!)。我已经在语法上对他的查询进行了一些清理(基于他的查询!):
SELECT
DATE(t1.`Production_date`) as theDate,
MAX( t1.`bundle_count` ) AS 'max(bundle_count)',
MAX( t1.`bundle_count` ) -
IF(
EXISTS
(
SELECT date(t2.production_date)
FROM input_example t2
WHERE t2.machine_no = 1 AND
date_sub(date(t1.production_date), interval 1 day) = date(t2.production_date)
),
(
SELECT MAX(t3.bundle_count)
FROM input_example t3
WHERE t3.machine_no = 1 AND
date_sub(date(t1.production_date), interval 1 day) = date(t3.production_date)
GROUP BY DATE(t3.production_date)
), 0
)
AS Total_Bundles_Used
FROM `input_example` t1
WHERE t1.machine_no = 1
GROUP BY DATE( t1.`production_date` )
注 1:我认为 @Grijesh 和我正在同时清理查询语法问题。令人鼓舞的是,在我们都进行清理之后,我们最终得到了非常相似的版本。IFNULL()
当没有前面的数据时,我的版本使用不同。我也得到了一个DATE_SUB
,我确保将各种日期减少到没有时间成分的单纯日期,通过DATE()
注2:我本来没有完全理解你的源表,所以我想我需要在查询中实现一个运行计数。但是经过更好的检查,很明显你的源数据已经有一个运行计数,所以我把那些东西拿回来了。
我不确定,但您需要这样的东西,希望它在某种程度上对您有所帮助:
试试这个:
SELECT t1.`Production_date` ,
MAX(t1.`bundle_count`) - MAX(t2.`bundle_count`) ,
COUNT(t1.`bundle_count`)
FROM `table_name` AS t1
INNER JOIN `table_name` AS t2
ON ABS(DATEDIFF(t1.`Production_date` , t2.`Production_date`)) = 1
GROUP BY t1.`Production_date`
编辑
我创建了一个表名 = 'table_name',如下所示,
mysql> SELECT * FROM `table_name`;
+---------------------+--------------+
| Production_date | bundle_count |
+---------------------+--------------+
| 2004-12-01 20:37:22 | 1 |
| 2004-12-01 20:37:22 | 2 |
| 2004-12-01 20:37:22 | 3 |
| 2004-12-02 20:37:22 | 2 |
| 2004-12-02 20:37:22 | 5 |
| 2004-12-02 20:37:22 | 7 |
| 2004-12-03 20:37:22 | 6 |
| 2004-12-03 20:37:22 | 7 |
| 2004-12-03 20:37:22 | 2 |
| 2004-12-04 20:37:22 | 1 |
| 2004-12-04 20:37:22 | 9 |
+---------------------+--------------+
11 rows in set (0.00 sec)
我的查询:查找 bundle_count
两个连续日期之间的差异:
SELECT t1.`Production_date` ,
MAX(t2.`bundle_count`) - MAX(t1.`bundle_count`) ,
COUNT(t1.`bundle_count`)
FROM `table_name` AS t1
INNER JOIN `table_name` AS t2
ON ABS(DATEDIFF(t1.`Production_date` , t2.`Production_date`)) = 1
GROUP BY t1.Production_date;
它的输出:
+---------------------+-------------------------------------------------+--------------------------+
| Production_date | MAX(t2.`bundle_count`) - MAX(t1.`bundle_count`) | COUNT(t1.`bundle_count`) |
+---------------------+-------------------------------------------------+--------------------------+
| 2004-12-01 20:37:22 | 4 | 9 |
| 2004-12-02 20:37:22 | 0 | 18 |
| 2004-12-03 20:37:22 | 2 | 15 |
| 2004-12-04 20:37:22 | -2 | 6 |
+---------------------+-------------------------------------------------+--------------------------+
4 rows in set (0.00 sec)
这是 PostgreSQL 语法(抱歉;这是我所熟悉的),但基本上应该适用于任一数据库。请注意,这也不完全在 PostgreSQL 中运行,因为group
它不是有效的表名(它是保留关键字)。正如其他人所提到的,该方法是一种自联接,但我使用了一个视图来处理每天的最大值和差异作为单独的步骤。
create view max_by_day as
select
date_trunc('day', production_date) as production_date,
max(bundle_count) as bundle_count
from
group
group by
date_trunc('day', production_date);
select
today.production_date as production_date,
today.bundle_count,
today.bundle_count - coalesce(yesterday.bundle_count, 0)
from
max_by_day as today
left join max_by_day yesterday on (yesterday.production_date = today.production_date - '1 day'::interval)
order by
production_date;
PostgreSQL 也有一个称为窗口函数的结构,它对此很有用并且更容易理解。只需要坚持一点主张就可以建立一个卓越的数据库。:-P
select
date_trunc('day', production_date),
max(bundle_count),
max(bundle_count) - lag(max(bundle_count), 1, 0)
over
(order by date_trunc('day', production_date))
from
group
group by
date_trunc('day', production_date);
这两种方法在处理数据中缺失天数的方式上有所不同——第一种将其视为 0,第二种将使用前一天存在的日期。你的样本中没有这样的案例,所以我不知道这是否是你关心的事情。