私はMySQLを初めて使用し、次のことを見つけようとしています。
ある日の最大値と前日の最大値の差が発生しました。
次の方法で日付の最大値を取得できました。
select max(`bundle_count`), `Production_date`
from `table`
group by `Production_date`
しかし、SQLを使用して、特定の2つの日付の最大値の差を計算する方法がわかりません。
このような出力を期待しています
私を助けてください。
更新 1:テストに使用したhttp://sqlfiddle.com/#!2/818ad/2というフィドルがあります。更新 2: Sandy のコメントに基づいて、さらに洗練/修正するために使用し
たフィドル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()
私のバージョンは、先行データがない場合の forの使い方が異なります。私も最終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
私のクエリ: 2つの連続した日付の 違いを見つけるに は:
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 の構文です (申し訳ありませんが、私がよく知っている構文です) が、基本的にはどちらのデータベースでも機能するはずです。group
は有効なテーブル名ではないため (これは予約済みのキーワードです)、これは PostgreSQL でも正確に実行されないことに注意してください。他の人が述べたように、アプローチは自己結合ですが、ビューを使用して、最大日と差を別々のステップとして処理しました。
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);
これらの 2 つのアプローチは、データ内の欠落した日の処理方法が異なります。最初のアプローチはそれを 0 として扱い、2 番目のアプローチは存在する前日を使用します。あなたのサンプルにはこのようなケースはありませんでしたので、これがあなたの関心事かどうかはわかりません。