最近、SQLで「えっ、そうなるの?」とびっくりしたことがあったので、シェアします!
データをまとめるときによく使うMAX()
関数。
「一番大きい値が欲しいだけでしょ」と思っていたんですが、複数のカラムをMAXでまとめるときには、意外な注意点があるんです。
実際のクエリを見てみる
例えば、こんなデータがあるとします👇
user_id | name | price |
---|---|---|
abc | BLACK | 1000 |
abc | APPLE | 4000 |
このデータを、user_id
ごとにまとめて、name
とprice
の最大値を出したいとします。
書いたクエリはこんな感じ。
WITH data_a AS (
SELECT 'abc' AS user_id, 'BLACK' AS name, 1000 AS price
UNION ALL
SELECT 'abc', 'APPLE', 4000
)
SELECT
user_id,
MAX(name) AS name,
MAX(price) AS max_price
FROM
data_a
GROUP BY
user_id;
実行結果はこうなる
user_id | name | max_price |
---|---|---|
abc | BLACK | 4000 |
「ん?え、ちょっと待って」って思いませんか?max_price
はちゃんと4000になっていますが、name
がBLACK
になっています。
でも、price = 4000
のときのname
って、APPLE
ですよね。
なぜこんな結果になるの?
実は、MAX()
はカラムごとに独立して計算されるんです。
つまり、name
カラムは「文字コード順で一番大きいもの(この場合BLACK)」、price
カラムは数値の最大値(4000)を、それぞれ別々に計算します。
だから、同じ行からname
とprice
をセットで持ってきてくれるわけじゃないんですね。
じゃあ正しくセットで欲しい場合は?
「最大のprice
のときのname
」を正しく取得したい場合は、
サブクエリやQUALIFY
句を使って、しっかりセットで取る必要があります。
BigQueryならこんな感じ👇
SELECT
user_id,
name,
price
FROM
data_a
QUALIFY
price = MAX(price) OVER(PARTITION BY user_id)
こうすると、price
が一番大きい行だけを絞り込んでくれるので、name
とprice
がちゃんとセットになります。
まとめ:MAXを使うときは気をつけよう!
実は私自身は、数字以外のカラムだとMAXを使うと何が最大と判断されるか不安になるので、あまり使わないようにしていました。他の人のSQLを見た時に、「こんなにMAX使って大丈夫なのか…?」と思ったことで、今回のことに気づきました。
「最大値といえばMAX!!」と思って使いがちな関数だと思うのですが、使う時は注意していきましょう〜!
今回のポイントをサクッとおさらい:
✅ MAX()
を複数カラムに使うと、それぞれ独立して計算される
✅ セットで正しいデータが欲しいなら、サブクエリやQUALIFY
で工夫する
✅ 特にレポートやLooker Studio用の集計では要注意!
こういった小さな気づきを、またブログで共有していきますね。
「他にもこういうパターン知りたい!」という方は、コメントやSNSで教えてください!
▼こちらもおすすめ

Comment