データベース

【解決】ORA-00979: GROUP BYの式ではありません。

  • このエントリーをはてなブックマークに追加
  • LINEで送る

Oracleで”GROUP BY”の使い方を間違うと…

「ORA-00979: GROUP BYの式ではありません」

というエラーが発生します。

『何だコレ?』

って思うカモですが、すぐに解決できます!

サクっと解決して、ササっと帰宅してダラダラしましょう^^

 

『ORA-00979のエラー原因はなんだろう…』

『どうやってエラーを解消するんだろう…』

このような疑問に答えます。


SEおっさん
SEおっさん
SE歴20年のオッサンが詳しく解説するぞい!

※保有資格:OracleMasterGold/JavaWebコンポーネントディベロッパ/応用情報技術者/簿記2級

【原因と解決策】ORA-00979: GROUP BYの式ではありません

まず、結論から!

「ORA-00979: GROUP BYの式ではありません」

このエラー原因と4つの解決方法について述べます。

GROUP BYの式ではありませんの原因

GROUP BYに存在しない項目を、SELECTしちゃったため

解決方法(4パターン)
  1. GROUP BYにSELECTしたい項目を追加する
  2. GROUP BYをやめてDISTINCTを指定する
  3. SELECTしたい項目に集約関数を使用する
  4. 分析関数を使用する
SEおっさん
SEおっさん
もうちょい、詳しく説明するぞい!

原因: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"
SEおっさん
SEおっさん
SE20年のオッサンでも、この間違いはやってしまいそうになります。
注意してね!


スポンサーリンク

解消法4つ:ORA-00979: GROUP BYの式ではありません。

ORA-00979: GROUP BYの式ではありません。

の解消法を4つご紹介します。

データ取得する目的に合った解消法を選んでみましょう!

解消法(その1):GROUP BYにSELECTしたい項目を追加する

GROUP BY句にSELECTしたい項目を追加します。

最もシンプルな解消法です。

例)項目「数学」をGROUP BY句に追加して指定してエラーを解消

SELECT
    性別, 数学
FROM クラス
GROUP BY 性別, 数学;

解消法(その2):DISTINCTを指定する

GROUP BY句を使用せずに、SELECTでDISTINCTを指定します。

単に重複データを削除したいだけなら、GROUP BYよりDISTINCTの方が記述量が少なくて済みます。

例)DISTINCTを指定して解消

SELECT
    DISTINCT 性別, 数学
FROM クラス

なお、
GROUP BYとDISTINCTの実行速度は環境・状況により異なります。

解消法(その3):SELECTしたい項目に集約関数を使用する

GROUP BYを指定されていないSELECT項目に集約関数を使用します。

例)集約関数MAX(最大を求める関数)で解消

SELECT
    性別, MAX(数学)
FROM クラス
GROUP BY 性別;

解消法(その4):分析関数を使用する

GROUP BYを指定していな項目に対して、分析関数(※)を使用して解消できます。
※)分析関数はwindow関数とも呼ばれます

「GROUP BY」の代わりに「PARTITION BY 」をSELECT項目の末尾にOVERを付けて指定します。

例)分析関数で解消

SELECT
    性別, 数学, MAX(数学) OVER(PARTITION BY 性別) AS 数学MAX
FROM クラス;

+-----------------+--------+--------+------+
| 名前            | 性別   | 数学   | 数学MAX  |
+-----------------+--------+--------+------+
| 青葉 一郎      | 男     | 85     | 94   |
| 石野 真央      | 女     | 31     | 72   |
| 真田 万吉      | 男     | 49     | 94   |
| 田中 佐助      | 男     | 40     | 94   |
| 月野 弥生      | 女     | 72     | 72   |
| 玉井 治夫      | 男     | 83     | 94   |
| 林田 啓二      | 男     | 94     | 94   |
| 山田 花子      | 女     | 43     | 72   |
+-----------------+--------+--------+

 

分析関数は難しいので、少し解説します。

OVER(PARTITION BY 性別)

の部分がGROUP BY 性別の代わりとなります。

GROUP BYより分析関数の方が問合せ速度は早いです。

また、

MySQLはバージョン8.0から分析関数(Window関数)が使用できます。

MariaDBはバージョン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を指定していない)項目を指定しても

エラーになりません。

え!結果は何を返すの?
たろちゃん
たろちゃん


SEおっさん
SEおっさん
アテにならない不確定な値を返すぞい

例えば、こんなSQLを実行したとします。

SELECT
    性別, 数学
FROM クラス
GROUP BY 性別;

Oracleの場合、『ORA-00979: GROUP BYの式ではありません。』のエラーとなりますが、

MariaDB(MySQL)の場合、エラーとならずに不確定な値(項目:数学)を返してます。

+--------+--------+
| 性別   | 数学   |
+--------+--------+
| 女     | 74     |
| 男     | 36     |
+--------+--------+

どの行を引っ張ってきてるかワカラナイ仕様です。
正直、エラーを返した方がマシやと思うねんけど…

 

SEおっさん
SEおっさん
ここまで読んでくれてありがとう!




スポンサーリンク
  • このエントリーをはてなブックマークに追加
  • LINEで送る

コメントを残す

*