SQL実践入門を読んでいて、挙動があまりイメージできなかったため調べたことを記載します。
内容はSQL実践入門を参考にさせていただいています。
サンプルコードはこちらで公開されています。
最初に結論
SUM関数内に複数列からなる式を入れると、各行の式で得られた結果を合計しているようでした。
以降で実際に試してみます
実行環境
- Windows10 Home
- Microsoft SQL Server 2019
テーブル作成
サンプルテーブルを作成します。
.sql
CREATE TABLE PriceByAge
(product_id VARCHAR(32) NOT NULL,
low_age INTEGER NOT NULL,
high_age INTEGER NOT NULL,
price INTEGER NOT NULL,
PRIMARY KEY (product_id, low_age),
CHECK (low_age < high_age));
データを作成します。
.sql
INSERT INTO PriceByAge VALUES('製品1', 0 , 50 , 2000);
INSERT INTO PriceByAge VALUES('製品1', 51 , 100 , 3000);
INSERT INTO PriceByAge VALUES('製品2', 0 , 100 , 4200);
INSERT INTO PriceByAge VALUES('製品3', 0 , 20 , 500);
INSERT INTO PriceByAge VALUES('製品3', 31 , 70 , 800);
INSERT INTO PriceByAge VALUES('製品3', 71 , 100 , 1000);
INSERT INTO PriceByAge VALUES('製品4', 0 , 99 , 8900);
SUM(a - b)を実行してみる
以下のコードでは、low_age ~ high_ageの値が0 ~ 100の連続になっている製品を取得しています。
.sql
SELECT product_id
FROM PriceByAge
GROUP BY product_id
HAVING SUM(high_age - low_age + 1) = 101;
※0から100までなので、値の数は101個あります
何が疑問だったのか
SUM関数内で計算式を渡したときは、どういう順序で計算されているんだろう?
ということでした。
サンプルコードを元に試してみる
改めてテーブルの全行を確認
.sql
SELECT * FROM PriceByAge;
各行ごと計算結果と製品ごとの合計値を両方出してみる
.sql
SELECT product_id,low_age,high_age,(high_age - low_age + 1) AS 行の計算結果,
SUM(high_age - low_age + 1)OVER( PARTITION BY PRODUCT_ID) AS SUM関数の結果
FROM PriceByAge
;
実行結果から理解できたこと
それぞれの実行結果を見ると以下の計算順序になっていることがわかります。
-
各行の(high_age - low_age + 1)が計算されている
-
括弧内の計算の後に、GROUP BY product_idによる集約が行われる
-
product_idごとにSUM関数による合計値の計算が行われる
感想
実際に調べてみると普通の四則演算と同じだなという感じで、
むしろなんで疑問に思ったのか不思議なレベルでした。
でも実際に動かしてみて腑に落ちたので良かったです。