SlideShare a Scribd company logo
プログラマのためのSQL
P492の難解SQL
テーブル定義
CREATE TABLE ProductTests
(batch_nbr INTEGER NOT NULL PRIMARY KEY,
prod_code CHAR(1) NOT NULL,
prod_quality DECIMAL(8,4) NOT NULL);
INSERT INTO ProductTests (batch_nbr, prod_code, prod_quality)
VALUES (1, 'A', 80),
(2, 'A', 70),
(3, 'A', 80),
(4, 'B', 60),
(5, 'B', 90),
(6, 'C', 80),
(7, 'D', 80),
(8, 'A', 50),
(9, 'C', 70);
問題のクエリ
SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr,
AVG(B4.prod_quality) AS avg_prod_quality
FROM (SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
GROUP BY B1.prod_code, B1.batch_nbr) AS X
INNER JOIN
ProductTests AS B4
ON B4.prod_code = X.prod_code
AND B4.batch_nbr = X.batch_nbr
GROUP BY X.prod_code, X.end_batch_nbr;
何がしたいクエリなのか?
製品のリストと品質スコアのデータを持つProductTestsというテーブルを考
えよう。このテーブルから、同じ製品のシーケンシャルなグループに対する品
質スコアの平均を求めたい。たとえば、製品Aのバッチ番号1、2、3に対する
平均品質スコアは、
(80+70+80)/3=76.6666…
といった具合だ。ここで注意が必要なのは、バッチ番号8番の製品Aのように、
飛び石になった場合は別グループとして扱うことだ。
Joe Celko. プログラマのためのSQL 第4版 すべてを知り尽くしたいあなたに
対象データと結果
対象データ
select * from ProductTests;
batch_nbr | prod_code | prod_quality
-----------+-----------+--------------
1 | A | 80.0000
2 | A | 70.0000
3 | A | 80.0000
4 | B | 60.0000
5 | B | 90.0000
6 | C | 80.0000
7 | D | 80.0000
8 | A | 50.0000
9 | C | 70.0000
(9 rows)
件のSQLの実行結果
prod_code | start_batch_nbr | end_batch_nbr | avg_prod_quality
-----------+-----------------+---------------+---------------------
A | 1 | 3 | 76.6666666666666667
B | 4 | 5 | 75.0000000000000000
C | 6 | 6 | 80.0000000000000000
D | 7 | 7 | 80.0000000000000000
A | 8 | 8 | 50.0000000000000000
C | 9 | 9 | 70.0000000000000000
(6 rows)
クエリ解説1※実行SQLは赤字で示します
SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr,
AVG(B4.prod_quality) AS avg_prod_quality
FROM (SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
GROUP BY B1.prod_code, B1.batch_nbr) AS X
INNER JOIN
ProductTests AS B4
ON B4.prod_code = X.prod_code
AND B4.batch_nbr = X.batch_nbr
GROUP BY X.prod_code, X.end_batch_nbr;
※注意1 SELECT句の列指定は*としました。
※注意2 わかりやすさのためOrder byを加えています(行順意外に結果はありません)
batch_nbr | prod_code | prod_quality | batch_nbr | prod_code | prod_quality
-----------+-----------+--------------+-----------+-----------+--------------
1 | A | 80.0000 | 1 | A | 80.0000
1 | A | 80.0000 | 2 | A | 70.0000
1 | A | 80.0000 | 3 | A | 80.0000
1 | A | 80.0000 | 8 | A | 50.0000
2 | A | 70.0000 | 2 | A | 70.0000
2 | A | 70.0000 | 3 | A | 80.0000
2 | A | 70.0000 | 8 | A | 50.0000
3 | A | 80.0000 | 3 | A | 80.0000
3 | A | 80.0000 | 8 | A | 50.0000
4 | B | 60.0000 | 4 | B | 60.0000
4 | B | 60.0000 | 5 | B | 90.0000
5 | B | 90.0000 | 5 | B | 90.0000
6 | C | 80.0000 | 6 | C | 80.0000
6 | C | 80.0000 | 9 | C | 70.0000
7 | D | 80.0000 | 7 | D | 80.0000
8 | A | 50.0000 | 8 | A | 50.0000
9 | C | 70.0000 | 9 | C | 70.0000
(17 rows)
※実行SQLは赤字で示します
SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr,
AVG(B4.prod_quality) AS avg_prod_quality
FROM (SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
GROUP BY B1.prod_code, B1.batch_nbr) AS X
INNER JOIN
ProductTests AS B4
ON B4.prod_code = X.prod_code
AND B4.batch_nbr = X.batch_nbr
GROUP BY X.prod_code, X.end_batch_nbr;
クエリ解説1-1
元データ
select * from ProductTests;
batch_nbr | prod_code | prod_quality
-----------+-----------+--------------
1 | A | 80.0000
2 | A | 70.0000
3 | A | 80.0000
4 | B | 60.0000
5 | B | 90.0000
6 | C | 80.0000
7 | D | 80.0000
8 | A | 50.0000
9 | C | 70.0000
prod_codeが同じでbatch_nbrが大きいものと自己結合します
Aに限って考えると、Aのバッチ番号は{1,2,3,8}なので
{11,12,13,18, 22,23,28, 33,38, 88}の10通りのペアができます
※注意1 SELECT句の列指定は*としました。
※注意2 わかりやすさのためOrder byを加えています(行順意外に結果はありません)
batch_nbr | prod_code | prod_quality | batch_nbr | prod_code | prod_quality
-----------+-----------+--------------+-----------+-----------+--------------
1 | A | 80.0000 | 1 | A | 80.0000
1 | A | 80.0000 | 2 | A | 70.0000
1 | A | 80.0000 | 3 | A | 80.0000
1 | A | 80.0000 | 8 | A | 50.0000
2 | A | 70.0000 | 2 | A | 70.0000
2 | A | 70.0000 | 3 | A | 80.0000
2 | A | 70.0000 | 8 | A | 50.0000
3 | A | 80.0000 | 3 | A | 80.0000
3 | A | 80.0000 | 8 | A | 50.0000
4 | B | 60.0000 | 4 | B | 60.0000
4 | B | 60.0000 | 5 | B | 90.0000
5 | B | 90.0000 | 5 | B | 90.0000
6 | C | 80.0000 | 6 | C | 80.0000
6 | C | 80.0000 | 9 | C | 70.0000
7 | D | 80.0000 | 7 | D | 80.0000
8 | A | 50.0000 | 8 | A | 50.0000
9 | C | 70.0000 | 9 | C | 70.0000
(17 rows)
SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
クエリ解説2※実行SQLは赤字で示します
SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr,
AVG(B4.prod_quality) AS avg_prod_quality
FROM (SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
GROUP BY B1.prod_code, B1.batch_nbr) AS X
INNER JOIN
ProductTests AS B4
ON B4.prod_code = X.prod_code
AND B4.batch_nbr = X.batch_nbr
GROUP BY X.prod_code, X.end_batch_nbr;
※注意1 SELECT句の列指定は*としました。
※注意2 わかりやすさのためOrder byを加えています(行順意外に結果はありません)
batch_nbr | prod_code | prod_quality | batch_nbr | prod_code | prod_quality
-----------+-----------+--------------+-----------+-----------+--------------
1 | A | 80.0000 | 1 | A | 80.0000
1 | A | 80.0000 | 2 | A | 70.0000
1 | A | 80.0000 | 3 | A | 80.0000
2 | A | 70.0000 | 2 | A | 70.0000
2 | A | 70.0000 | 3 | A | 80.0000
3 | A | 80.0000 | 3 | A | 80.0000
4 | B | 60.0000 | 4 | B | 60.0000
4 | B | 60.0000 | 5 | B | 90.0000
5 | B | 90.0000 | 5 | B | 90.0000
6 | C | 80.0000 | 6 | C | 80.0000
7 | D | 80.0000 | 7 | D | 80.0000
8 | A | 50.0000 | 8 | A | 50.0000
9 | C | 70.0000 | 9 | C | 70.0000
(13 rows)
※実行SQLは赤字で示します
SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr,
AVG(B4.prod_quality) AS avg_prod_quality
FROM (SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
GROUP BY B1.prod_code, B1.batch_nbr) AS X
INNER JOIN
ProductTests AS B4
ON B4.prod_code = X.prod_code
AND B4.batch_nbr = X.batch_nbr
GROUP BY X.prod_code, X.end_batch_nbr;
SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
クエリ解説2-1
青色の行が消えます
batch_nbr | prod_code | prod_quality | batch_nbr | prod_quality
-----------+-----------+--------------+-----------+--------------
1 | A | 80.0000 | 1 | 80.0000
1 | A | 80.0000 | 2 | 70.0000
1 | A | 80.0000 | 3 | 80.0000
1 | A | 80.0000 | 8 | 50.0000
2 | A | 70.0000 | 2 | 70.0000
2 | A | 70.0000 | 3 | 80.0000
2 | A | 70.0000 | 8 | 50.0000
3 | A | 80.0000 | 3 | 80.0000
3 | A | 80.0000 | 8 | 50.0000
4 | B | 60.0000 | 4 | 60.0000
4 | B | 60.0000 | 5 | 90.0000
5 | B | 90.0000 | 5 | 90.0000
6 | C | 80.0000 | 6 | 80.0000
6 | C | 80.0000 | 9 | 70.0000
7 | D | 80.0000 | 7 | 80.0000
8 | A | 50.0000 | 8 | 50.0000
9 | C | 70.0000 | 9 | 70.0000
(17 rows)
※注意1 SELECT句の列指定は*としました。
※注意2 わかりやすさのためOrder byを加えています(行順意外に結果はありません)
batch_nbr | prod_code | prod_quality | batch_nbr | prod_code | prod_quality
-----------+-----------+--------------+-----------+-----------+--------------
1 | A | 80.0000 | 1 | A | 80.0000
1 | A | 80.0000 | 2 | A | 70.0000
1 | A | 80.0000 | 3 | A | 80.0000
2 | A | 70.0000 | 2 | A | 70.0000
2 | A | 70.0000 | 3 | A | 80.0000
3 | A | 80.0000 | 3 | A | 80.0000
4 | B | 60.0000 | 4 | B | 60.0000
4 | B | 60.0000 | 5 | B | 90.0000
5 | B | 90.0000 | 5 | B | 90.0000
6 | C | 80.0000 | 6 | C | 80.0000
7 | D | 80.0000 | 7 | D | 80.0000
8 | A | 50.0000 | 8 | A | 50.0000
9 | C | 70.0000 | 9 | C | 70.0000
(13 rows)
またまたAに限ったケースで考えると…
※実行SQLは赤字で示します
SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr,
AVG(B4.prod_quality) AS avg_prod_quality
FROM (SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
GROUP BY B1.prod_code, B1.batch_nbr) AS X
INNER JOIN
ProductTests AS B4
ON B4.prod_code = X.prod_code
AND B4.batch_nbr = X.batch_nbr
GROUP BY X.prod_code, X.end_batch_nbr;
SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
クエリ解説2-2
青色の行が消えます
batch_nbr | prod_code | prod_quality | batch_nbr | prod_quality
-----------+-----------+--------------+-----------+--------------
1 | A | 80.0000 | 1 | 80.0000
1 | A | 80.0000 | 2 | 70.0000
1 | A | 80.0000 | 3 | 80.0000
1 | A | 80.0000 | 8 | 50.0000
2 | A | 70.0000 | 2 | 70.0000
2 | A | 70.0000 | 3 | 80.0000
2 | A | 70.0000 | 8 | 50.0000
3 | A | 80.0000 | 3 | 80.0000
3 | A | 80.0000 | 8 | 50.0000
4 | B | 60.0000 | 4 | 60.0000
4 | B | 60.0000 | 5 | 90.0000
5 | B | 90.0000 | 5 | 90.0000
6 | C | 80.0000 | 6 | 80.0000
6 | C | 80.0000 | 9 | 70.0000
7 | D | 80.0000 | 7 | 80.0000
8 | A | 50.0000 | 8 | 50.0000
9 | C | 70.0000 | 9 | 70.0000
(17 rows)
※注意1 SELECT句の列指定は*としました。
※注意2 わかりやすさのためOrder byを加えています(行順意外に結果はありません)
batch_nbr | prod_code | prod_quality | batch_nbr | prod_code | prod_quality
-----------+-----------+--------------+-----------+-----------+--------------
1 | A | 80.0000 | 1 | A | 80.0000
1 | A | 80.0000 | 2 | A | 70.0000
1 | A | 80.0000 | 3 | A | 80.0000
2 | A | 70.0000 | 2 | A | 70.0000
2 | A | 70.0000 | 3 | A | 80.0000
3 | A | 80.0000 | 3 | A | 80.0000
4 | B | 60.0000 | 4 | B | 60.0000
4 | B | 60.0000 | 5 | B | 90.0000
5 | B | 90.0000 | 5 | B | 90.0000
6 | C | 80.0000 | 6 | C | 80.0000
7 | D | 80.0000 | 7 | D | 80.0000
8 | A | 50.0000 | 8 | A | 50.0000
9 | C | 70.0000 | 9 | C | 70.0000
(13 rows)
ALL述語の条件は若干わかりにくいが、
自己結合したテーブル
B1とB2において、
B1.batch_nbr B2.batch_nbr
間のprod_codeの値が
全て一致する行を残すための相関サブクエリ
1 3や2 3間は全てAなので残る
2 8間では、4にB、6にCが混じるので
ALL述語が成り立たない。=消える
クエリ解説3※実行SQLは赤字で示します
SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr,
AVG(B4.prod_quality) AS avg_prod_quality
FROM (SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
GROUP BY B1.prod_code, B1.batch_nbr) AS X
INNER JOIN
ProductTests AS B4
ON B4.prod_code = X.prod_code
AND B4.batch_nbr = X.batch_nbr
GROUP BY X.prod_code, X.end_batch_nbr;
prod_code | batch_nbr | end_batch_nbr
-----------+-----------+---------------
A | 1 | 3
A | 2 | 3
A | 3 | 3
B | 4 | 5
B | 5 | 5
C | 6 | 6
D | 7 | 7
A | 8 | 8
C | 9 | 9
(9 rows)
クエリ解説3-1※実行SQLは赤字で示します
SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr,
AVG(B4.prod_quality) AS avg_prod_quality
FROM (SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
GROUP BY B1.prod_code, B1.batch_nbr) AS X
INNER JOIN
ProductTests AS B4
ON B4.prod_code = X.prod_code
AND B4.batch_nbr = X.batch_nbr
GROUP BY X.prod_code, X.end_batch_nbr;
prod_code | batch_nbr | end_batch_nbr
-----------+-----------+---------------
A | 1 | 3
A | 2 | 3
A | 3 | 3
B | 4 | 5
B | 5 | 5
C | 6 | 6
D | 7 | 7
A | 8 | 8
C | 9 | 9
(9 rows)
対象データ
select * from ProductTests;
batch_nbr | prod_code | prod_quality
-----------+-----------+--------------
1 | A | 80.0000
2 | A | 70.0000
3 | A | 80.0000
4 | B | 60.0000
5 | B | 90.0000
6 | C | 80.0000
7 | D | 80.0000
8 | A | 50.0000
9 | C | 70.0000
(9 rows)
連続している製品グループ群の最後のbatch_nbrを
end_batch_nbrに格納している
クエリ解説4※実行SQLは赤字で示します
SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr,
AVG(B4.prod_quality) AS avg_prod_quality
FROM (SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
GROUP BY B1.prod_code, B1.batch_nbr) AS X
INNER JOIN
ProductTests AS B4
ON B4.prod_code = X.prod_code
AND B4.batch_nbr = X.batch_nbr
GROUP BY X.prod_code, X.end_batch_nbr;
※赤字の部分のまま実行できないのでselect * from ()で括ってサブクエリとして実行しています
prod_code | batch_nbr | end_batch_nbr | prod_quality
-----------+-----------+---------------+--------------
A | 1 | 3 | 80.0000
A | 2 | 3 | 70.0000
A | 3 | 3 | 80.0000
B | 4 | 5 | 60.0000
B | 5 | 5 | 90.0000
C | 6 | 6 | 80.0000
D | 7 | 7 | 80.0000
A | 8 | 8 | 50.0000
C | 9 | 9 | 70.0000
(9 rows)
内部結合でprod_qualityを付け足しただけ。
クエリ解説5※実行SQLは赤字で示します
SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr,
AVG(B4.prod_quality) AS avg_prod_quality
FROM (SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
GROUP BY B1.prod_code, B1.batch_nbr) AS X
INNER JOIN
ProductTests AS B4
ON B4.prod_code = X.prod_code
AND B4.batch_nbr = X.batch_nbr
GROUP BY X.prod_code, X.end_batch_nbr;
prod_code | start_batch_nbr | end_batch_nbr | avg_prod_quality
-----------+-----------------+---------------+---------------------
A | 1 | 3 | 76.6666666666666667
B | 4 | 5 | 75.0000000000000000
C | 6 | 6 | 80.0000000000000000
D | 7 | 7 | 80.0000000000000000
A | 8 | 8 | 50.0000000000000000
C | 9 | 9 | 70.0000000000000000
(6 rows)
赤字の列でgroup by。
・最小値(同じ製品のシーケンシャルなグループの開始位置)
・平均値
を集計関数で計算して表示
完成
対象データ
select * from ProductTests;
batch_nbr | prod_code | prod_quality
-----------+-----------+--------------
1 | A | 80.0000
2 | A | 70.0000
3 | A | 80.0000
4 | B | 60.0000
5 | B | 90.0000
6 | C | 80.0000
7 | D | 80.0000
8 | A | 50.0000
9 | C | 70.0000
(9 rows)
prod_code | start_batch_nbr | end_batch_nbr | avg_prod_quality
-----------+-----------------+---------------+---------------------
A | 1 | 3 | 76.6666666666666667
B | 4 | 5 | 75.0000000000000000
C | 6 | 6 | 80.0000000000000000
D | 7 | 7 | 80.0000000000000000
A | 8 | 8 | 50.0000000000000000
C | 9 | 9 | 70.0000000000000000
(6 rows)
おさらい1※実行SQLは赤字で示します
SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr,
AVG(B4.prod_quality) AS avg_prod_quality
FROM (SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
GROUP BY B1.prod_code, B1.batch_nbr) AS X
INNER JOIN
ProductTests AS B4
ON B4.prod_code = X.prod_code
AND B4.batch_nbr = X.batch_nbr
GROUP BY X.prod_code, X.end_batch_nbr;
※注意1 SELECT句の列指定は*としました。
※注意2 わかりやすさのためOrder byを加えています(行順意外に結果はありません)
batch_nbr | prod_code | prod_quality | batch_nbr | prod_code | prod_quality
-----------+-----------+--------------+-----------+-----------+--------------
1 | A | 80.0000 | 1 | A | 80.0000
1 | A | 80.0000 | 2 | A | 70.0000
1 | A | 80.0000 | 3 | A | 80.0000
1 | A | 80.0000 | 8 | A | 50.0000
2 | A | 70.0000 | 2 | A | 70.0000
2 | A | 70.0000 | 3 | A | 80.0000
2 | A | 70.0000 | 8 | A | 50.0000
3 | A | 80.0000 | 3 | A | 80.0000
3 | A | 80.0000 | 8 | A | 50.0000
4 | B | 60.0000 | 4 | B | 60.0000
4 | B | 60.0000 | 5 | B | 90.0000
5 | B | 90.0000 | 5 | B | 90.0000
6 | C | 80.0000 | 6 | C | 80.0000
6 | C | 80.0000 | 9 | C | 70.0000
7 | D | 80.0000 | 7 | D | 80.0000
8 | A | 50.0000 | 8 | A | 50.0000
9 | C | 70.0000 | 9 | C | 70.0000
(17 rows)
おさらい2※実行SQLは赤字で示します
SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr,
AVG(B4.prod_quality) AS avg_prod_quality
FROM (SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
GROUP BY B1.prod_code, B1.batch_nbr) AS X
INNER JOIN
ProductTests AS B4
ON B4.prod_code = X.prod_code
AND B4.batch_nbr = X.batch_nbr
GROUP BY X.prod_code, X.end_batch_nbr;
※注意1 SELECT句の列指定は*としました。
※注意2 わかりやすさのためOrder byを加えています(行順意外に結果はありません)
batch_nbr | prod_code | prod_quality | batch_nbr | prod_code | prod_quality
-----------+-----------+--------------+-----------+-----------+--------------
1 | A | 80.0000 | 1 | A | 80.0000
1 | A | 80.0000 | 2 | A | 70.0000
1 | A | 80.0000 | 3 | A | 80.0000
2 | A | 70.0000 | 2 | A | 70.0000
2 | A | 70.0000 | 3 | A | 80.0000
3 | A | 80.0000 | 3 | A | 80.0000
4 | B | 60.0000 | 4 | B | 60.0000
4 | B | 60.0000 | 5 | B | 90.0000
5 | B | 90.0000 | 5 | B | 90.0000
6 | C | 80.0000 | 6 | C | 80.0000
7 | D | 80.0000 | 7 | D | 80.0000
8 | A | 50.0000 | 8 | A | 50.0000
9 | C | 70.0000 | 9 | C | 70.0000
(13 rows)
おさらい3※実行SQLは赤字で示します
SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr,
AVG(B4.prod_quality) AS avg_prod_quality
FROM (SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
GROUP BY B1.prod_code, B1.batch_nbr) AS X
INNER JOIN
ProductTests AS B4
ON B4.prod_code = X.prod_code
AND B4.batch_nbr = X.batch_nbr
GROUP BY X.prod_code, X.end_batch_nbr;
prod_code | batch_nbr | end_batch_nbr
-----------+-----------+---------------
A | 1 | 3
A | 2 | 3
A | 3 | 3
B | 4 | 5
B | 5 | 5
C | 6 | 6
D | 7 | 7
A | 8 | 8
C | 9 | 9
(9 rows)
おさらい4※実行SQLは赤字で示します
SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr,
AVG(B4.prod_quality) AS avg_prod_quality
FROM (SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
GROUP BY B1.prod_code, B1.batch_nbr) AS X
INNER JOIN
ProductTests AS B4
ON B4.prod_code = X.prod_code
AND B4.batch_nbr = X.batch_nbr
GROUP BY X.prod_code, X.end_batch_nbr;
※赤字の部分のまま実行できないのでselect * from ()で括ってサブクエリとして実行しています
prod_code | batch_nbr | end_batch_nbr | prod_quality
-----------+-----------+---------------+--------------
A | 1 | 3 | 80.0000
A | 2 | 3 | 70.0000
A | 3 | 3 | 80.0000
B | 4 | 5 | 60.0000
B | 5 | 5 | 90.0000
C | 6 | 6 | 80.0000
D | 7 | 7 | 80.0000
A | 8 | 8 | 50.0000
C | 9 | 9 | 70.0000
(9 rows)
内部結合でprod_qualityを付け足しただけ。
おさらい5※実行SQLは赤字で示します
SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr,
AVG(B4.prod_quality) AS avg_prod_quality
FROM (SELECT B1.prod_code, B1.batch_nbr,
MAX(B2.batch_nbr) AS end_batch_nbr
FROM ProductTests AS B1, ProductTests AS B2
WHERE B1.batch_nbr <= B2.batch_nbr
AND B1.prod_code = B2.prod_code
AND B1.prod_code
= ALL (SELECT prod_code
FROM ProductTests AS B3
WHERE B3.batch_nbr BETWEEN B1.batch_nbr
AND B2.batch_nbr)
GROUP BY B1.prod_code, B1.batch_nbr) AS X
INNER JOIN
ProductTests AS B4
ON B4.prod_code = X.prod_code
AND B4.batch_nbr = X.batch_nbr
GROUP BY X.prod_code, X.end_batch_nbr;
prod_code | start_batch_nbr | end_batch_nbr | avg_prod_quality
-----------+-----------------+---------------+---------------------
A | 1 | 3 | 76.6666666666666667
B | 4 | 5 | 75.0000000000000000
C | 6 | 6 | 80.0000000000000000
D | 7 | 7 | 80.0000000000000000
A | 8 | 8 | 50.0000000000000000
C | 9 | 9 | 70.0000000000000000
(6 rows)
赤字の列でgroup by。
・最小値(同じ製品のシーケンシャルなグループの開始位置)
・平均値
を集計関数で計算して表示

More Related Content

Similar to プログラマのためのSQL読書会補助資料

Managing Statistics for Optimal Query Performance
Managing Statistics for Optimal Query PerformanceManaging Statistics for Optimal Query Performance
Managing Statistics for Optimal Query Performance
Karen Morton
 
A high speed tree-based 64-bit cmos binary comparator
A high speed tree-based 64-bit cmos binary comparatorA high speed tree-based 64-bit cmos binary comparator
A high speed tree-based 64-bit cmos binary comparator
eSAT Publishing House
 
High speed tree-based 64-bit cmos binary comparator
High speed tree-based 64-bit cmos binary comparatorHigh speed tree-based 64-bit cmos binary comparator
High speed tree-based 64-bit cmos binary comparator
eSAT Journals
 
12c SQL Plan Directives
12c SQL Plan Directives12c SQL Plan Directives
12c SQL Plan Directives
Franck Pachot
 
Informix Warehouse Accelerator (IWA) features in version 12.1
Informix Warehouse Accelerator (IWA) features in version 12.1Informix Warehouse Accelerator (IWA) features in version 12.1
Informix Warehouse Accelerator (IWA) features in version 12.1
Keshav Murthy
 
Writing efficient sql
Writing efficient sqlWriting efficient sql
Writing efficient sql
j9soto
 
Exadata - Smart Scan Testing
Exadata - Smart Scan TestingExadata - Smart Scan Testing
Exadata - Smart Scan Testing
Monowar Mukul
 
Interpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratchInterpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratch
National Cheng Kung University
 
70 433
70 43370 433
Pro PostgreSQL
Pro PostgreSQLPro PostgreSQL
Pro PostgreSQL
Robert Treat
 
Introduction to SQL Antipatterns
Introduction to SQL AntipatternsIntroduction to SQL Antipatterns
Introduction to SQL Antipatterns
Krishnakumar S
 
Big Data Analytics with MariaDB ColumnStore
Big Data Analytics with MariaDB ColumnStoreBig Data Analytics with MariaDB ColumnStore
Big Data Analytics with MariaDB ColumnStore
MariaDB plc
 
Execution plans for mere mortals
Execution plans for mere mortalsExecution plans for mere mortals
Execution plans for mere mortals
Mike Lawell
 
Introduction to Parallel Execution
Introduction to Parallel ExecutionIntroduction to Parallel Execution
Introduction to Parallel Execution
Doug Burns
 
Explaining the Postgres Query Optimizer
Explaining the Postgres Query OptimizerExplaining the Postgres Query Optimizer
Explaining the Postgres Query Optimizer
EDB
 
Automated parameter optimization should be included in future 
defect predict...
Automated parameter optimization should be included in future 
defect predict...Automated parameter optimization should be included in future 
defect predict...
Automated parameter optimization should be included in future 
defect predict...
Chakkrit (Kla) Tantithamthavorn
 
GSP 215 RANK Become Exceptional--gsp215rank.com
GSP 215 RANK Become Exceptional--gsp215rank.comGSP 215 RANK Become Exceptional--gsp215rank.com
GSP 215 RANK Become Exceptional--gsp215rank.com
claric119
 
GSP 215 RANK Achievement Education--gsp215rank.com
GSP 215 RANK Achievement Education--gsp215rank.comGSP 215 RANK Achievement Education--gsp215rank.com
GSP 215 RANK Achievement Education--gsp215rank.com
claric169
 
sqltuningcardinality1(1).ppt
sqltuningcardinality1(1).pptsqltuningcardinality1(1).ppt
sqltuningcardinality1(1).ppt
TricantinoLopezPerez
 
Mid term sem 2 1415 sol
Mid term sem 2 1415 solMid term sem 2 1415 sol
Mid term sem 2 1415 sol
IIUM
 

Similar to プログラマのためのSQL読書会補助資料 (20)

Managing Statistics for Optimal Query Performance
Managing Statistics for Optimal Query PerformanceManaging Statistics for Optimal Query Performance
Managing Statistics for Optimal Query Performance
 
A high speed tree-based 64-bit cmos binary comparator
A high speed tree-based 64-bit cmos binary comparatorA high speed tree-based 64-bit cmos binary comparator
A high speed tree-based 64-bit cmos binary comparator
 
High speed tree-based 64-bit cmos binary comparator
High speed tree-based 64-bit cmos binary comparatorHigh speed tree-based 64-bit cmos binary comparator
High speed tree-based 64-bit cmos binary comparator
 
12c SQL Plan Directives
12c SQL Plan Directives12c SQL Plan Directives
12c SQL Plan Directives
 
Informix Warehouse Accelerator (IWA) features in version 12.1
Informix Warehouse Accelerator (IWA) features in version 12.1Informix Warehouse Accelerator (IWA) features in version 12.1
Informix Warehouse Accelerator (IWA) features in version 12.1
 
Writing efficient sql
Writing efficient sqlWriting efficient sql
Writing efficient sql
 
Exadata - Smart Scan Testing
Exadata - Smart Scan TestingExadata - Smart Scan Testing
Exadata - Smart Scan Testing
 
Interpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratchInterpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratch
 
70 433
70 43370 433
70 433
 
Pro PostgreSQL
Pro PostgreSQLPro PostgreSQL
Pro PostgreSQL
 
Introduction to SQL Antipatterns
Introduction to SQL AntipatternsIntroduction to SQL Antipatterns
Introduction to SQL Antipatterns
 
Big Data Analytics with MariaDB ColumnStore
Big Data Analytics with MariaDB ColumnStoreBig Data Analytics with MariaDB ColumnStore
Big Data Analytics with MariaDB ColumnStore
 
Execution plans for mere mortals
Execution plans for mere mortalsExecution plans for mere mortals
Execution plans for mere mortals
 
Introduction to Parallel Execution
Introduction to Parallel ExecutionIntroduction to Parallel Execution
Introduction to Parallel Execution
 
Explaining the Postgres Query Optimizer
Explaining the Postgres Query OptimizerExplaining the Postgres Query Optimizer
Explaining the Postgres Query Optimizer
 
Automated parameter optimization should be included in future 
defect predict...
Automated parameter optimization should be included in future 
defect predict...Automated parameter optimization should be included in future 
defect predict...
Automated parameter optimization should be included in future 
defect predict...
 
GSP 215 RANK Become Exceptional--gsp215rank.com
GSP 215 RANK Become Exceptional--gsp215rank.comGSP 215 RANK Become Exceptional--gsp215rank.com
GSP 215 RANK Become Exceptional--gsp215rank.com
 
GSP 215 RANK Achievement Education--gsp215rank.com
GSP 215 RANK Achievement Education--gsp215rank.comGSP 215 RANK Achievement Education--gsp215rank.com
GSP 215 RANK Achievement Education--gsp215rank.com
 
sqltuningcardinality1(1).ppt
sqltuningcardinality1(1).pptsqltuningcardinality1(1).ppt
sqltuningcardinality1(1).ppt
 
Mid term sem 2 1415 sol
Mid term sem 2 1415 solMid term sem 2 1415 sol
Mid term sem 2 1415 sol
 

Recently uploaded

Experts live - Improving user adoption with AI
Experts live - Improving user adoption with AIExperts live - Improving user adoption with AI
Experts live - Improving user adoption with AI
jitskeb
 
Learn SQL from basic queries to Advance queries
Learn SQL from basic queries to Advance queriesLearn SQL from basic queries to Advance queries
Learn SQL from basic queries to Advance queries
manishkhaire30
 
STATATHON: Unleashing the Power of Statistics in a 48-Hour Knowledge Extravag...
STATATHON: Unleashing the Power of Statistics in a 48-Hour Knowledge Extravag...STATATHON: Unleashing the Power of Statistics in a 48-Hour Knowledge Extravag...
STATATHON: Unleashing the Power of Statistics in a 48-Hour Knowledge Extravag...
sameer shah
 
一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理
一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理
一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理
nuttdpt
 
Orchestrating the Future: Navigating Today's Data Workflow Challenges with Ai...
Orchestrating the Future: Navigating Today's Data Workflow Challenges with Ai...Orchestrating the Future: Navigating Today's Data Workflow Challenges with Ai...
Orchestrating the Future: Navigating Today's Data Workflow Challenges with Ai...
Kaxil Naik
 
4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...
4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...
4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...
Social Samosa
 
Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...
Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...
Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...
Aggregage
 
一比一原版(UCSF文凭证书)旧金山分校毕业证如何办理
一比一原版(UCSF文凭证书)旧金山分校毕业证如何办理一比一原版(UCSF文凭证书)旧金山分校毕业证如何办理
一比一原版(UCSF文凭证书)旧金山分校毕业证如何办理
nuttdpt
 
一比一原版(harvard毕业证书)哈佛大学毕业证如何办理
一比一原版(harvard毕业证书)哈佛大学毕业证如何办理一比一原版(harvard毕业证书)哈佛大学毕业证如何办理
一比一原版(harvard毕业证书)哈佛大学毕业证如何办理
taqyea
 
Analysis insight about a Flyball dog competition team's performance
Analysis insight about a Flyball dog competition team's performanceAnalysis insight about a Flyball dog competition team's performance
Analysis insight about a Flyball dog competition team's performance
roli9797
 
一比一原版兰加拉学院毕业证(Langara毕业证书)学历如何办理
一比一原版兰加拉学院毕业证(Langara毕业证书)学历如何办理一比一原版兰加拉学院毕业证(Langara毕业证书)学历如何办理
一比一原版兰加拉学院毕业证(Langara毕业证书)学历如何办理
hyfjgavov
 
Build applications with generative AI on Google Cloud
Build applications with generative AI on Google CloudBuild applications with generative AI on Google Cloud
Build applications with generative AI on Google Cloud
Márton Kodok
 
办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样
办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样
办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样
apvysm8
 
A presentation that explain the Power BI Licensing
A presentation that explain the Power BI LicensingA presentation that explain the Power BI Licensing
A presentation that explain the Power BI Licensing
AlessioFois2
 
一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理
一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理
一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理
nyfuhyz
 
Population Growth in Bataan: The effects of population growth around rural pl...
Population Growth in Bataan: The effects of population growth around rural pl...Population Growth in Bataan: The effects of population growth around rural pl...
Population Growth in Bataan: The effects of population growth around rural pl...
Bill641377
 
Predictably Improve Your B2B Tech Company's Performance by Leveraging Data
Predictably Improve Your B2B Tech Company's Performance by Leveraging DataPredictably Improve Your B2B Tech Company's Performance by Leveraging Data
Predictably Improve Your B2B Tech Company's Performance by Leveraging Data
Kiwi Creative
 
在线办理(英国UCA毕业证书)创意艺术大学毕业证在读证明一模一样
在线办理(英国UCA毕业证书)创意艺术大学毕业证在读证明一模一样在线办理(英国UCA毕业证书)创意艺术大学毕业证在读证明一模一样
在线办理(英国UCA毕业证书)创意艺术大学毕业证在读证明一模一样
v7oacc3l
 
DATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docx
DATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docxDATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docx
DATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docx
SaffaIbrahim1
 
Challenges of Nation Building-1.pptx with more important
Challenges of Nation Building-1.pptx with more importantChallenges of Nation Building-1.pptx with more important
Challenges of Nation Building-1.pptx with more important
Sm321
 

Recently uploaded (20)

Experts live - Improving user adoption with AI
Experts live - Improving user adoption with AIExperts live - Improving user adoption with AI
Experts live - Improving user adoption with AI
 
Learn SQL from basic queries to Advance queries
Learn SQL from basic queries to Advance queriesLearn SQL from basic queries to Advance queries
Learn SQL from basic queries to Advance queries
 
STATATHON: Unleashing the Power of Statistics in a 48-Hour Knowledge Extravag...
STATATHON: Unleashing the Power of Statistics in a 48-Hour Knowledge Extravag...STATATHON: Unleashing the Power of Statistics in a 48-Hour Knowledge Extravag...
STATATHON: Unleashing the Power of Statistics in a 48-Hour Knowledge Extravag...
 
一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理
一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理
一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理
 
Orchestrating the Future: Navigating Today's Data Workflow Challenges with Ai...
Orchestrating the Future: Navigating Today's Data Workflow Challenges with Ai...Orchestrating the Future: Navigating Today's Data Workflow Challenges with Ai...
Orchestrating the Future: Navigating Today's Data Workflow Challenges with Ai...
 
4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...
4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...
4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...
 
Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...
Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...
Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...
 
一比一原版(UCSF文凭证书)旧金山分校毕业证如何办理
一比一原版(UCSF文凭证书)旧金山分校毕业证如何办理一比一原版(UCSF文凭证书)旧金山分校毕业证如何办理
一比一原版(UCSF文凭证书)旧金山分校毕业证如何办理
 
一比一原版(harvard毕业证书)哈佛大学毕业证如何办理
一比一原版(harvard毕业证书)哈佛大学毕业证如何办理一比一原版(harvard毕业证书)哈佛大学毕业证如何办理
一比一原版(harvard毕业证书)哈佛大学毕业证如何办理
 
Analysis insight about a Flyball dog competition team's performance
Analysis insight about a Flyball dog competition team's performanceAnalysis insight about a Flyball dog competition team's performance
Analysis insight about a Flyball dog competition team's performance
 
一比一原版兰加拉学院毕业证(Langara毕业证书)学历如何办理
一比一原版兰加拉学院毕业证(Langara毕业证书)学历如何办理一比一原版兰加拉学院毕业证(Langara毕业证书)学历如何办理
一比一原版兰加拉学院毕业证(Langara毕业证书)学历如何办理
 
Build applications with generative AI on Google Cloud
Build applications with generative AI on Google CloudBuild applications with generative AI on Google Cloud
Build applications with generative AI on Google Cloud
 
办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样
办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样
办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样
 
A presentation that explain the Power BI Licensing
A presentation that explain the Power BI LicensingA presentation that explain the Power BI Licensing
A presentation that explain the Power BI Licensing
 
一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理
一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理
一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理
 
Population Growth in Bataan: The effects of population growth around rural pl...
Population Growth in Bataan: The effects of population growth around rural pl...Population Growth in Bataan: The effects of population growth around rural pl...
Population Growth in Bataan: The effects of population growth around rural pl...
 
Predictably Improve Your B2B Tech Company's Performance by Leveraging Data
Predictably Improve Your B2B Tech Company's Performance by Leveraging DataPredictably Improve Your B2B Tech Company's Performance by Leveraging Data
Predictably Improve Your B2B Tech Company's Performance by Leveraging Data
 
在线办理(英国UCA毕业证书)创意艺术大学毕业证在读证明一模一样
在线办理(英国UCA毕业证书)创意艺术大学毕业证在读证明一模一样在线办理(英国UCA毕业证书)创意艺术大学毕业证在读证明一模一样
在线办理(英国UCA毕业证书)创意艺术大学毕业证在读证明一模一样
 
DATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docx
DATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docxDATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docx
DATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docx
 
Challenges of Nation Building-1.pptx with more important
Challenges of Nation Building-1.pptx with more importantChallenges of Nation Building-1.pptx with more important
Challenges of Nation Building-1.pptx with more important
 

プログラマのためのSQL読書会補助資料

  • 2. テーブル定義 CREATE TABLE ProductTests (batch_nbr INTEGER NOT NULL PRIMARY KEY, prod_code CHAR(1) NOT NULL, prod_quality DECIMAL(8,4) NOT NULL); INSERT INTO ProductTests (batch_nbr, prod_code, prod_quality) VALUES (1, 'A', 80), (2, 'A', 70), (3, 'A', 80), (4, 'B', 60), (5, 'B', 90), (6, 'C', 80), (7, 'D', 80), (8, 'A', 50), (9, 'C', 70);
  • 3. 問題のクエリ SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr, AVG(B4.prod_quality) AS avg_prod_quality FROM (SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) GROUP BY B1.prod_code, B1.batch_nbr) AS X INNER JOIN ProductTests AS B4 ON B4.prod_code = X.prod_code AND B4.batch_nbr = X.batch_nbr GROUP BY X.prod_code, X.end_batch_nbr;
  • 5. 対象データと結果 対象データ select * from ProductTests; batch_nbr | prod_code | prod_quality -----------+-----------+-------------- 1 | A | 80.0000 2 | A | 70.0000 3 | A | 80.0000 4 | B | 60.0000 5 | B | 90.0000 6 | C | 80.0000 7 | D | 80.0000 8 | A | 50.0000 9 | C | 70.0000 (9 rows) 件のSQLの実行結果 prod_code | start_batch_nbr | end_batch_nbr | avg_prod_quality -----------+-----------------+---------------+--------------------- A | 1 | 3 | 76.6666666666666667 B | 4 | 5 | 75.0000000000000000 C | 6 | 6 | 80.0000000000000000 D | 7 | 7 | 80.0000000000000000 A | 8 | 8 | 50.0000000000000000 C | 9 | 9 | 70.0000000000000000 (6 rows)
  • 6. クエリ解説1※実行SQLは赤字で示します SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr, AVG(B4.prod_quality) AS avg_prod_quality FROM (SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) GROUP BY B1.prod_code, B1.batch_nbr) AS X INNER JOIN ProductTests AS B4 ON B4.prod_code = X.prod_code AND B4.batch_nbr = X.batch_nbr GROUP BY X.prod_code, X.end_batch_nbr; ※注意1 SELECT句の列指定は*としました。 ※注意2 わかりやすさのためOrder byを加えています(行順意外に結果はありません) batch_nbr | prod_code | prod_quality | batch_nbr | prod_code | prod_quality -----------+-----------+--------------+-----------+-----------+-------------- 1 | A | 80.0000 | 1 | A | 80.0000 1 | A | 80.0000 | 2 | A | 70.0000 1 | A | 80.0000 | 3 | A | 80.0000 1 | A | 80.0000 | 8 | A | 50.0000 2 | A | 70.0000 | 2 | A | 70.0000 2 | A | 70.0000 | 3 | A | 80.0000 2 | A | 70.0000 | 8 | A | 50.0000 3 | A | 80.0000 | 3 | A | 80.0000 3 | A | 80.0000 | 8 | A | 50.0000 4 | B | 60.0000 | 4 | B | 60.0000 4 | B | 60.0000 | 5 | B | 90.0000 5 | B | 90.0000 | 5 | B | 90.0000 6 | C | 80.0000 | 6 | C | 80.0000 6 | C | 80.0000 | 9 | C | 70.0000 7 | D | 80.0000 | 7 | D | 80.0000 8 | A | 50.0000 | 8 | A | 50.0000 9 | C | 70.0000 | 9 | C | 70.0000 (17 rows)
  • 7. ※実行SQLは赤字で示します SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr, AVG(B4.prod_quality) AS avg_prod_quality FROM (SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) GROUP BY B1.prod_code, B1.batch_nbr) AS X INNER JOIN ProductTests AS B4 ON B4.prod_code = X.prod_code AND B4.batch_nbr = X.batch_nbr GROUP BY X.prod_code, X.end_batch_nbr; クエリ解説1-1 元データ select * from ProductTests; batch_nbr | prod_code | prod_quality -----------+-----------+-------------- 1 | A | 80.0000 2 | A | 70.0000 3 | A | 80.0000 4 | B | 60.0000 5 | B | 90.0000 6 | C | 80.0000 7 | D | 80.0000 8 | A | 50.0000 9 | C | 70.0000 prod_codeが同じでbatch_nbrが大きいものと自己結合します Aに限って考えると、Aのバッチ番号は{1,2,3,8}なので {11,12,13,18, 22,23,28, 33,38, 88}の10通りのペアができます ※注意1 SELECT句の列指定は*としました。 ※注意2 わかりやすさのためOrder byを加えています(行順意外に結果はありません) batch_nbr | prod_code | prod_quality | batch_nbr | prod_code | prod_quality -----------+-----------+--------------+-----------+-----------+-------------- 1 | A | 80.0000 | 1 | A | 80.0000 1 | A | 80.0000 | 2 | A | 70.0000 1 | A | 80.0000 | 3 | A | 80.0000 1 | A | 80.0000 | 8 | A | 50.0000 2 | A | 70.0000 | 2 | A | 70.0000 2 | A | 70.0000 | 3 | A | 80.0000 2 | A | 70.0000 | 8 | A | 50.0000 3 | A | 80.0000 | 3 | A | 80.0000 3 | A | 80.0000 | 8 | A | 50.0000 4 | B | 60.0000 | 4 | B | 60.0000 4 | B | 60.0000 | 5 | B | 90.0000 5 | B | 90.0000 | 5 | B | 90.0000 6 | C | 80.0000 | 6 | C | 80.0000 6 | C | 80.0000 | 9 | C | 70.0000 7 | D | 80.0000 | 7 | D | 80.0000 8 | A | 50.0000 | 8 | A | 50.0000 9 | C | 70.0000 | 9 | C | 70.0000 (17 rows) SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code
  • 8. クエリ解説2※実行SQLは赤字で示します SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr, AVG(B4.prod_quality) AS avg_prod_quality FROM (SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) GROUP BY B1.prod_code, B1.batch_nbr) AS X INNER JOIN ProductTests AS B4 ON B4.prod_code = X.prod_code AND B4.batch_nbr = X.batch_nbr GROUP BY X.prod_code, X.end_batch_nbr; ※注意1 SELECT句の列指定は*としました。 ※注意2 わかりやすさのためOrder byを加えています(行順意外に結果はありません) batch_nbr | prod_code | prod_quality | batch_nbr | prod_code | prod_quality -----------+-----------+--------------+-----------+-----------+-------------- 1 | A | 80.0000 | 1 | A | 80.0000 1 | A | 80.0000 | 2 | A | 70.0000 1 | A | 80.0000 | 3 | A | 80.0000 2 | A | 70.0000 | 2 | A | 70.0000 2 | A | 70.0000 | 3 | A | 80.0000 3 | A | 80.0000 | 3 | A | 80.0000 4 | B | 60.0000 | 4 | B | 60.0000 4 | B | 60.0000 | 5 | B | 90.0000 5 | B | 90.0000 | 5 | B | 90.0000 6 | C | 80.0000 | 6 | C | 80.0000 7 | D | 80.0000 | 7 | D | 80.0000 8 | A | 50.0000 | 8 | A | 50.0000 9 | C | 70.0000 | 9 | C | 70.0000 (13 rows)
  • 9. ※実行SQLは赤字で示します SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr, AVG(B4.prod_quality) AS avg_prod_quality FROM (SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) GROUP BY B1.prod_code, B1.batch_nbr) AS X INNER JOIN ProductTests AS B4 ON B4.prod_code = X.prod_code AND B4.batch_nbr = X.batch_nbr GROUP BY X.prod_code, X.end_batch_nbr; SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) クエリ解説2-1 青色の行が消えます batch_nbr | prod_code | prod_quality | batch_nbr | prod_quality -----------+-----------+--------------+-----------+-------------- 1 | A | 80.0000 | 1 | 80.0000 1 | A | 80.0000 | 2 | 70.0000 1 | A | 80.0000 | 3 | 80.0000 1 | A | 80.0000 | 8 | 50.0000 2 | A | 70.0000 | 2 | 70.0000 2 | A | 70.0000 | 3 | 80.0000 2 | A | 70.0000 | 8 | 50.0000 3 | A | 80.0000 | 3 | 80.0000 3 | A | 80.0000 | 8 | 50.0000 4 | B | 60.0000 | 4 | 60.0000 4 | B | 60.0000 | 5 | 90.0000 5 | B | 90.0000 | 5 | 90.0000 6 | C | 80.0000 | 6 | 80.0000 6 | C | 80.0000 | 9 | 70.0000 7 | D | 80.0000 | 7 | 80.0000 8 | A | 50.0000 | 8 | 50.0000 9 | C | 70.0000 | 9 | 70.0000 (17 rows) ※注意1 SELECT句の列指定は*としました。 ※注意2 わかりやすさのためOrder byを加えています(行順意外に結果はありません) batch_nbr | prod_code | prod_quality | batch_nbr | prod_code | prod_quality -----------+-----------+--------------+-----------+-----------+-------------- 1 | A | 80.0000 | 1 | A | 80.0000 1 | A | 80.0000 | 2 | A | 70.0000 1 | A | 80.0000 | 3 | A | 80.0000 2 | A | 70.0000 | 2 | A | 70.0000 2 | A | 70.0000 | 3 | A | 80.0000 3 | A | 80.0000 | 3 | A | 80.0000 4 | B | 60.0000 | 4 | B | 60.0000 4 | B | 60.0000 | 5 | B | 90.0000 5 | B | 90.0000 | 5 | B | 90.0000 6 | C | 80.0000 | 6 | C | 80.0000 7 | D | 80.0000 | 7 | D | 80.0000 8 | A | 50.0000 | 8 | A | 50.0000 9 | C | 70.0000 | 9 | C | 70.0000 (13 rows) またまたAに限ったケースで考えると…
  • 10. ※実行SQLは赤字で示します SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr, AVG(B4.prod_quality) AS avg_prod_quality FROM (SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) GROUP BY B1.prod_code, B1.batch_nbr) AS X INNER JOIN ProductTests AS B4 ON B4.prod_code = X.prod_code AND B4.batch_nbr = X.batch_nbr GROUP BY X.prod_code, X.end_batch_nbr; SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) クエリ解説2-2 青色の行が消えます batch_nbr | prod_code | prod_quality | batch_nbr | prod_quality -----------+-----------+--------------+-----------+-------------- 1 | A | 80.0000 | 1 | 80.0000 1 | A | 80.0000 | 2 | 70.0000 1 | A | 80.0000 | 3 | 80.0000 1 | A | 80.0000 | 8 | 50.0000 2 | A | 70.0000 | 2 | 70.0000 2 | A | 70.0000 | 3 | 80.0000 2 | A | 70.0000 | 8 | 50.0000 3 | A | 80.0000 | 3 | 80.0000 3 | A | 80.0000 | 8 | 50.0000 4 | B | 60.0000 | 4 | 60.0000 4 | B | 60.0000 | 5 | 90.0000 5 | B | 90.0000 | 5 | 90.0000 6 | C | 80.0000 | 6 | 80.0000 6 | C | 80.0000 | 9 | 70.0000 7 | D | 80.0000 | 7 | 80.0000 8 | A | 50.0000 | 8 | 50.0000 9 | C | 70.0000 | 9 | 70.0000 (17 rows) ※注意1 SELECT句の列指定は*としました。 ※注意2 わかりやすさのためOrder byを加えています(行順意外に結果はありません) batch_nbr | prod_code | prod_quality | batch_nbr | prod_code | prod_quality -----------+-----------+--------------+-----------+-----------+-------------- 1 | A | 80.0000 | 1 | A | 80.0000 1 | A | 80.0000 | 2 | A | 70.0000 1 | A | 80.0000 | 3 | A | 80.0000 2 | A | 70.0000 | 2 | A | 70.0000 2 | A | 70.0000 | 3 | A | 80.0000 3 | A | 80.0000 | 3 | A | 80.0000 4 | B | 60.0000 | 4 | B | 60.0000 4 | B | 60.0000 | 5 | B | 90.0000 5 | B | 90.0000 | 5 | B | 90.0000 6 | C | 80.0000 | 6 | C | 80.0000 7 | D | 80.0000 | 7 | D | 80.0000 8 | A | 50.0000 | 8 | A | 50.0000 9 | C | 70.0000 | 9 | C | 70.0000 (13 rows) ALL述語の条件は若干わかりにくいが、 自己結合したテーブル B1とB2において、 B1.batch_nbr B2.batch_nbr 間のprod_codeの値が 全て一致する行を残すための相関サブクエリ 1 3や2 3間は全てAなので残る 2 8間では、4にB、6にCが混じるので ALL述語が成り立たない。=消える
  • 11. クエリ解説3※実行SQLは赤字で示します SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr, AVG(B4.prod_quality) AS avg_prod_quality FROM (SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) GROUP BY B1.prod_code, B1.batch_nbr) AS X INNER JOIN ProductTests AS B4 ON B4.prod_code = X.prod_code AND B4.batch_nbr = X.batch_nbr GROUP BY X.prod_code, X.end_batch_nbr; prod_code | batch_nbr | end_batch_nbr -----------+-----------+--------------- A | 1 | 3 A | 2 | 3 A | 3 | 3 B | 4 | 5 B | 5 | 5 C | 6 | 6 D | 7 | 7 A | 8 | 8 C | 9 | 9 (9 rows)
  • 12. クエリ解説3-1※実行SQLは赤字で示します SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr, AVG(B4.prod_quality) AS avg_prod_quality FROM (SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) GROUP BY B1.prod_code, B1.batch_nbr) AS X INNER JOIN ProductTests AS B4 ON B4.prod_code = X.prod_code AND B4.batch_nbr = X.batch_nbr GROUP BY X.prod_code, X.end_batch_nbr; prod_code | batch_nbr | end_batch_nbr -----------+-----------+--------------- A | 1 | 3 A | 2 | 3 A | 3 | 3 B | 4 | 5 B | 5 | 5 C | 6 | 6 D | 7 | 7 A | 8 | 8 C | 9 | 9 (9 rows) 対象データ select * from ProductTests; batch_nbr | prod_code | prod_quality -----------+-----------+-------------- 1 | A | 80.0000 2 | A | 70.0000 3 | A | 80.0000 4 | B | 60.0000 5 | B | 90.0000 6 | C | 80.0000 7 | D | 80.0000 8 | A | 50.0000 9 | C | 70.0000 (9 rows) 連続している製品グループ群の最後のbatch_nbrを end_batch_nbrに格納している
  • 13. クエリ解説4※実行SQLは赤字で示します SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr, AVG(B4.prod_quality) AS avg_prod_quality FROM (SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) GROUP BY B1.prod_code, B1.batch_nbr) AS X INNER JOIN ProductTests AS B4 ON B4.prod_code = X.prod_code AND B4.batch_nbr = X.batch_nbr GROUP BY X.prod_code, X.end_batch_nbr; ※赤字の部分のまま実行できないのでselect * from ()で括ってサブクエリとして実行しています prod_code | batch_nbr | end_batch_nbr | prod_quality -----------+-----------+---------------+-------------- A | 1 | 3 | 80.0000 A | 2 | 3 | 70.0000 A | 3 | 3 | 80.0000 B | 4 | 5 | 60.0000 B | 5 | 5 | 90.0000 C | 6 | 6 | 80.0000 D | 7 | 7 | 80.0000 A | 8 | 8 | 50.0000 C | 9 | 9 | 70.0000 (9 rows) 内部結合でprod_qualityを付け足しただけ。
  • 14. クエリ解説5※実行SQLは赤字で示します SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr, AVG(B4.prod_quality) AS avg_prod_quality FROM (SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) GROUP BY B1.prod_code, B1.batch_nbr) AS X INNER JOIN ProductTests AS B4 ON B4.prod_code = X.prod_code AND B4.batch_nbr = X.batch_nbr GROUP BY X.prod_code, X.end_batch_nbr; prod_code | start_batch_nbr | end_batch_nbr | avg_prod_quality -----------+-----------------+---------------+--------------------- A | 1 | 3 | 76.6666666666666667 B | 4 | 5 | 75.0000000000000000 C | 6 | 6 | 80.0000000000000000 D | 7 | 7 | 80.0000000000000000 A | 8 | 8 | 50.0000000000000000 C | 9 | 9 | 70.0000000000000000 (6 rows) 赤字の列でgroup by。 ・最小値(同じ製品のシーケンシャルなグループの開始位置) ・平均値 を集計関数で計算して表示
  • 15. 完成 対象データ select * from ProductTests; batch_nbr | prod_code | prod_quality -----------+-----------+-------------- 1 | A | 80.0000 2 | A | 70.0000 3 | A | 80.0000 4 | B | 60.0000 5 | B | 90.0000 6 | C | 80.0000 7 | D | 80.0000 8 | A | 50.0000 9 | C | 70.0000 (9 rows) prod_code | start_batch_nbr | end_batch_nbr | avg_prod_quality -----------+-----------------+---------------+--------------------- A | 1 | 3 | 76.6666666666666667 B | 4 | 5 | 75.0000000000000000 C | 6 | 6 | 80.0000000000000000 D | 7 | 7 | 80.0000000000000000 A | 8 | 8 | 50.0000000000000000 C | 9 | 9 | 70.0000000000000000 (6 rows)
  • 16. おさらい1※実行SQLは赤字で示します SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr, AVG(B4.prod_quality) AS avg_prod_quality FROM (SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) GROUP BY B1.prod_code, B1.batch_nbr) AS X INNER JOIN ProductTests AS B4 ON B4.prod_code = X.prod_code AND B4.batch_nbr = X.batch_nbr GROUP BY X.prod_code, X.end_batch_nbr; ※注意1 SELECT句の列指定は*としました。 ※注意2 わかりやすさのためOrder byを加えています(行順意外に結果はありません) batch_nbr | prod_code | prod_quality | batch_nbr | prod_code | prod_quality -----------+-----------+--------------+-----------+-----------+-------------- 1 | A | 80.0000 | 1 | A | 80.0000 1 | A | 80.0000 | 2 | A | 70.0000 1 | A | 80.0000 | 3 | A | 80.0000 1 | A | 80.0000 | 8 | A | 50.0000 2 | A | 70.0000 | 2 | A | 70.0000 2 | A | 70.0000 | 3 | A | 80.0000 2 | A | 70.0000 | 8 | A | 50.0000 3 | A | 80.0000 | 3 | A | 80.0000 3 | A | 80.0000 | 8 | A | 50.0000 4 | B | 60.0000 | 4 | B | 60.0000 4 | B | 60.0000 | 5 | B | 90.0000 5 | B | 90.0000 | 5 | B | 90.0000 6 | C | 80.0000 | 6 | C | 80.0000 6 | C | 80.0000 | 9 | C | 70.0000 7 | D | 80.0000 | 7 | D | 80.0000 8 | A | 50.0000 | 8 | A | 50.0000 9 | C | 70.0000 | 9 | C | 70.0000 (17 rows)
  • 17. おさらい2※実行SQLは赤字で示します SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr, AVG(B4.prod_quality) AS avg_prod_quality FROM (SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) GROUP BY B1.prod_code, B1.batch_nbr) AS X INNER JOIN ProductTests AS B4 ON B4.prod_code = X.prod_code AND B4.batch_nbr = X.batch_nbr GROUP BY X.prod_code, X.end_batch_nbr; ※注意1 SELECT句の列指定は*としました。 ※注意2 わかりやすさのためOrder byを加えています(行順意外に結果はありません) batch_nbr | prod_code | prod_quality | batch_nbr | prod_code | prod_quality -----------+-----------+--------------+-----------+-----------+-------------- 1 | A | 80.0000 | 1 | A | 80.0000 1 | A | 80.0000 | 2 | A | 70.0000 1 | A | 80.0000 | 3 | A | 80.0000 2 | A | 70.0000 | 2 | A | 70.0000 2 | A | 70.0000 | 3 | A | 80.0000 3 | A | 80.0000 | 3 | A | 80.0000 4 | B | 60.0000 | 4 | B | 60.0000 4 | B | 60.0000 | 5 | B | 90.0000 5 | B | 90.0000 | 5 | B | 90.0000 6 | C | 80.0000 | 6 | C | 80.0000 7 | D | 80.0000 | 7 | D | 80.0000 8 | A | 50.0000 | 8 | A | 50.0000 9 | C | 70.0000 | 9 | C | 70.0000 (13 rows)
  • 18. おさらい3※実行SQLは赤字で示します SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr, AVG(B4.prod_quality) AS avg_prod_quality FROM (SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) GROUP BY B1.prod_code, B1.batch_nbr) AS X INNER JOIN ProductTests AS B4 ON B4.prod_code = X.prod_code AND B4.batch_nbr = X.batch_nbr GROUP BY X.prod_code, X.end_batch_nbr; prod_code | batch_nbr | end_batch_nbr -----------+-----------+--------------- A | 1 | 3 A | 2 | 3 A | 3 | 3 B | 4 | 5 B | 5 | 5 C | 6 | 6 D | 7 | 7 A | 8 | 8 C | 9 | 9 (9 rows)
  • 19. おさらい4※実行SQLは赤字で示します SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr, AVG(B4.prod_quality) AS avg_prod_quality FROM (SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) GROUP BY B1.prod_code, B1.batch_nbr) AS X INNER JOIN ProductTests AS B4 ON B4.prod_code = X.prod_code AND B4.batch_nbr = X.batch_nbr GROUP BY X.prod_code, X.end_batch_nbr; ※赤字の部分のまま実行できないのでselect * from ()で括ってサブクエリとして実行しています prod_code | batch_nbr | end_batch_nbr | prod_quality -----------+-----------+---------------+-------------- A | 1 | 3 | 80.0000 A | 2 | 3 | 70.0000 A | 3 | 3 | 80.0000 B | 4 | 5 | 60.0000 B | 5 | 5 | 90.0000 C | 6 | 6 | 80.0000 D | 7 | 7 | 80.0000 A | 8 | 8 | 50.0000 C | 9 | 9 | 70.0000 (9 rows) 内部結合でprod_qualityを付け足しただけ。
  • 20. おさらい5※実行SQLは赤字で示します SELECT X.prod_code, MIN(X.batch_nbr) AS start_batch_nbr, end_batch_nbr, AVG(B4.prod_quality) AS avg_prod_quality FROM (SELECT B1.prod_code, B1.batch_nbr, MAX(B2.batch_nbr) AS end_batch_nbr FROM ProductTests AS B1, ProductTests AS B2 WHERE B1.batch_nbr <= B2.batch_nbr AND B1.prod_code = B2.prod_code AND B1.prod_code = ALL (SELECT prod_code FROM ProductTests AS B3 WHERE B3.batch_nbr BETWEEN B1.batch_nbr AND B2.batch_nbr) GROUP BY B1.prod_code, B1.batch_nbr) AS X INNER JOIN ProductTests AS B4 ON B4.prod_code = X.prod_code AND B4.batch_nbr = X.batch_nbr GROUP BY X.prod_code, X.end_batch_nbr; prod_code | start_batch_nbr | end_batch_nbr | avg_prod_quality -----------+-----------------+---------------+--------------------- A | 1 | 3 | 76.6666666666666667 B | 4 | 5 | 75.0000000000000000 C | 6 | 6 | 80.0000000000000000 D | 7 | 7 | 80.0000000000000000 A | 8 | 8 | 50.0000000000000000 C | 9 | 9 | 70.0000000000000000 (6 rows) 赤字の列でgroup by。 ・最小値(同じ製品のシーケンシャルなグループの開始位置) ・平均値 を集計関数で計算して表示