最近、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