はじめに
データベースを利用する目的の1つとして、
リレーショナルデータベースとSQLにおいては、
そうすると当然、
具体的には、
まあ、
まずは基本
直近を求める
まずは基本的な時系列分析から始めましょう。時系列にデータを比較する場合、
sample_ | load |
---|---|
2008-02-01 | 1024 |
2008-02-02 | 2366 |
2008-02-05 | 2366 |
2008-02-07 | 985 |
2008-02-08 | 780 |
2008-02-12 | 1000 |
まずは、
SELECT sample_date AS cur_date,
MIN(sample_date)
OVER (ORDER BY sample_date ASC
ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest
FROM LoadSample;
cur_date latest -------- -------- 08-02-01 08-02-02 08-02-01 08-02-05 08-02-02 08-02-07 08-02-05 08-02-08 08-02-07 08-02-12 08-02-08
2月1日より前のデータはこのテーブルには登録されていないので、
これを実装非依存のクエリにするには、
SELECT LS0.sample_date AS cur_date,
(SELECT MAX(sample_date)
FROM LoadSample LS1
WHERE LS1.sample_date < LS0.sample_date) AS latest
FROM LoadSample LS0;
これも結果はリスト1と同じです。ポイントはWHERE句の
SELECT LS0.sample_date AS cur_date,
MAX(LS1.sample_date) AS latest
FROM LoadSample LS0
LEFT OUTER JOIN LoadSample LS1
ON LS1.sample_date < LS0.sample_date
GROUP BY LS0.sample_date;
この自己結合の場合も、
SELECT LS0.sample_date AS cur_date,
LS1.sample_date AS latest
FROM LoadSample LS0
LEFT OUTER JOIN LoadSample LS1
ON LS1.sample_date < LS0.sample_date;
cur_date latest -------- -------- 08-02-01 ← S0:2月1日より小さい日付は 1つもないので、0個 08-02-02 08-02-01 ← S1:2月2日より小さい日付は1個 08-02-05 08-02-01 ← S2:2月5日より小さい日付は2個 08-02-05 08-02-02 08-02-07 08-02-01 ← S3:2月7日より小さい日付は3個 08-02-07 08-02-02 08-02-07 08-02-05 08-02-08 08-02-01 ← S4:2月8日より小さい日付は4個 08-02-08 08-02-02 08-02-08 08-02-05 08-02-08 08-02-07 08-02-12 08-02-01 ← S5:2月12日より小さい日付は5個 08-02-12 08-02-02 08-02-12 08-02-05 08-02-12 08-02-07 08-02-12 08-02-08
このように、
S0~S5の部分集合は、
![画像](/assets/images/dev/serial/01/sql_academy/0005/thumb/TH800_0005-01.png)
という包含関係のある部分集合群です
現在の日付の処理量と、
SELECT LS0.sample_date AS cur_date,
MAX(LS0.load_amt) AS cur_load_amt,
MAX(LS1.sample_date) AS latest,
(SELECT MAX(load_amt)
FROM LoadSample
WHERE sample_date = MAX(LS1.sample_date)) AS latest_load_amt
FROM LoadSample LS0
LEFT OUTER JOIN LoadSample LS1
ON LS1.sample_date < LS0.sample_date
GROUP BY LS0.sample_date;
cur_date cur_load_amt latest latest_load_amt ---------- --------- ---------- ----------- 2008-02-01 1024 2008-02-02 2366 2008-02-01 1024 2008-02-05 2366 2008-02-02 2366 2008-02-07 985 2008-02-05 2366 2008-02-08 780 2008-02-07 985 2008-02-12 1000 2008-02-08 780
ただし注意が必要なのは、
そこで代替案として、
SELECT LS0.sample_date AS cur_date,
LS0.load_amt AS cur_load,
LS1.sample_date AS latest,
LS1.load_amt AS latest_load
FROM LoadSample LS0
LEFT OUTER JOIN LoadSample LS1
ON LS1.sample_date = (SELECT MAX(sample_date)
FROM LoadSample
WHERE sample_date < LS0.sample_date);
これも結果は先ほどと同じになります