Oracleで”GROUP BY”の使い方を間違うと…
「ORA-00979: GROUP BYの式ではありません」
というエラーが発生します。
『何だコレ?』
って思うカモですが、すぐに解決できます!
サクっと解決して、ササっと帰宅してダラダラしましょう^^
『ORA-00979のエラー原因はなんだろう…』
『どうやってエラーを解消するんだろう…』
こんな疑問に答えます。
本記事の動画です。耳で聞きたい場合はどうぞ♪
【原因と解決策】ORA-00979: GROUP BYの式ではありません
まず、結論から!
「ORA-00979: GROUP BYの式ではありません」
このエラー原因と4つの解決方法について述べます。
GROUP BYに存在しない項目をSELECTしてるため
- GROUP BYにSELECTしたい項目を追加する
- GROUP BYをやめてDISTINCTを指定する
- SELECTしたい項目に集約関数を使用する
- 分析関数を使用する
原因:ORA-00979: GROUP BYの式ではありません。
『ORA-00979: GROUP BYの式ではありません。』
原因は…
GROUP BY句を使用した場合、
SELECT項目はGROUP BYで指定してない項目を使用できない
という決まりがあるからです。
エラー例【ORA-00979: GROUP BYの式ではありません】
ORA-00979が発生するSELECT文の実行例です。
性別は男女、数学は点数だとします。
SELECT
性別, 数学
FROM クラス
GROUP BY 性別;
ORA-00979: GROUP BYの式ではありません。 00979. 00000 - "not a GROUP BY expression"
性別と数学をSELECTしてますが、数学がGROUP BYに存在しないのでエラーとなります。
エラー内容が「GROUP BYに項目が存在しません」だったらわかりやすいですけどね ^^;
注意してね!
解消法4つ:ORA-00979: GROUP BYの式ではありません。
『ORA-00979: GROUP BYの式ではありません。』
の解消法を4つご紹介します。
データ取得する目的に合った解消法を選んでみましょう!
解消法(その1):GROUP BYにSELECTしたい項目を追加する
GROUP BY句にSELECTしたい項目を追加します。
最もシンプルな解消法です。
例)GROUP BY句に項目「数学」を追加してエラーを解消
SELECT
性別, 数学
FROM クラス
GROUP BY 性別, 数学
;
-+--------+--------+ | 性別 | 数学 | -+--------+--------+ | 男 | 85 | | 女 | 43 | | 女 | 72 | | 男 | 94 | -+--------+--------+
SELECT項目とGROUP BYの項目が一致していますね。
これでエラーは解消され、男女別の数学の点数を重複除外で表示します。
一番シンプルな解決策です。
解消法(その2):DISTINCTを指定する
GROUP BY句を使用せずに、SELECTでDISTINCTを指定します。
単に重複データを削除したいだけなら、GROUP BYよりDISTINCTの方が記述量が少なくて済みます。
例)DISTINCTを指定して解消
SELECT
DISTINCT 性別, 数学
FROM クラス;
-+--------+--------+ | 性別 | 数学 | -+--------+--------+ | 男 | 85 | | 女 | 43 | | 女 | 72 | | 男 | 94 | -+--------+--------+
GROUP BY句を無くして、DISTINCTで代用していますね。
なお、
GROUP BYとDISTINCTの実行速度は環境・状況により異なります。
解消法(その3):SELECTしたい項目に集約関数を使用する
GROUP BYを指定されていないSELECT項目に集約関数を使用します。
例)集約関数MAX(最大を求める関数)で解消
SELECT
性別, MAX(数学)
FROM クラス
GROUP BY 性別;
-+--------+--------+ | 性別 | 数学 | -+--------+--------+ | 女 | 72 | | 男 | 94 | -+--------+--------+
Group By句に数学は追加してませんが、SELECT句にMAX(数学)としてますね。
こうすると、性別毎の数学の最高得点が取得できます。
解消法(その4):分析関数を使用する
GROUP BYを指定していな項目に対して、分析関数(※)を使用して解消できます。
※)分析関数はwindow関数とも呼ばれます
「GROUP BY」の代わりに「PARTITION BY 」をSELECT項目の末尾にOVERを付けて指定します。
例)分析関数で解消
SELECT
性別, 数学, MAX(数学) OVER(PARTITION BY 性別) AS 数学MAX
FROM クラス;
+-----------------+--------+--------+------+ | 名前 | 性別 | 数学 | 数学MAX | +-----------------+--------+--------+------+ | 青葉 一郎 | 男 | 85 | 94 | | 石野 真央 | 女 | 43 | 72 | | 田中 佐助 | 男 | 85 | 94 | | 月野 弥生 | 女 | 72 | 72 | | 林田 啓二 | 男 | 94 | 94 | | 山田 花子 | 女 | 43 | 72 | +-----------------+--------+--------+
分析関数は難しいので、少し解説します。
OVER(PARTITION BY 性別)
の部分がGROUP BY 性別の代わりとなります。
GROUP BYより分析関数の方が問合せ速度は早いです。
また、
MySQLはバージョン8.0から分析関数(Window関数)が使用できます。
MariaDBはバージョン10.2から分析関数が使用できます。
バージョン10.2未満だと、下記のようなエラーがでちゃう(-_-)
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(PARTITION BY 性別) AS avg from クラス' at line 5
(上記の例題で扱った分析関数付きSELECT文を実行した場合のエラー)
MariaDB(MySQL)はGROUP BY未指定でもエラーじゃない
MariaDB(MySQL)の場合、
GROUP BY句において、
SELECT項目に集約していない(GROUP BYを指定してない)項目
を使用してもエラーになりません。
例えば、こんなSQLを実行したとします。
SELECT
性別, 数学
FROM クラス
GROUP BY 性別;
Oracleの場合、『ORA-00979: GROUP BYの式ではありません。』のエラーとなりますが、
MariaDB(MySQL)の場合、エラーとならずに不確定な値(項目:数学)を返してます。
+--------+--------+ | 性別 | 数学 | +--------+--------+ | 女 | 74 | | 男 | 36 | +--------+--------+
どの行を引っ張ってきてるかワカラナイ仕様です。
正直、エラーを返した方がマシやと思うねんけど…
本記事では伝えきれないこともありました。
『もう少し詳細を知りたいよ~』
という場合はココナラを覗いてみてね♪
SQL文の基本とエラー解消のコツ等を教えます~SQL文・プロシージャ作成やパフォーマンス改善もご相談を~
「記事を読んでもわからないトコがある」「内容が変だよ」
という時は、お気軽にコメントください♪
「もっとSEおっさんに詳しく聞きたい。何かお願いしたい!」
という時は、ココナラまで。メッセージもお気軽に♪
LINEでのお問合わせも受付中!
LINE公式アカウント
メッセージをお待ちしています!
- 応用情報技術者
- Oracle Master Gold
- Java SE Gold
- Java EE Webコンポーネントディベロッパ
- Python エンジニア認定データ分析
- 簿記2級