ハードディスクメンテナンス

投稿記事数[8640]以上!PC,旧ゲーム,カメラ,動画などを、アヤしゐ專門妖語を使ッて解説スル!

MySQLに於けるGROUP BYでのミス(集約キー以外を書いてしまう)

   


スポンサーリンク

テーブル名:商品一覧
商品名,販売単価,仕入単価
品目A,1000,700
品目B,2000,1400
品目C,3000,2100
品目D,1000,700
品目E,2000,1400
品目F,1000,700

というテーブルがあるとして、ここから、販売価格でGROUP BYする。

SELECT `販売価格`,COUNT(*)
FROM `商品一覧`
GROUP BY `販売価格`

結果は

販売単価,数
1000,3
2000,2
3000,1

となる。

ここで、

SELECT `商品名`,`販売価格`,COUNT(*)
FROM `商品一覧`
GROUP BY `販売価格`

としてしまうとエラー。

MySQLではエラーとはならずに通ってしまう(※)が、このSQL文に問題があることはすぐに分かる。

商品名,販売単価,数
,1000,3
,2000,2
,3000,1

アは販売単価が1,000円の集合だが、販売単価が1,000円の商品は、品目A、品目D、品目Fの3商品がある。
で、アには、その内のどれを表示すればいいのか?

イは販売単価が2,000円の集合だが、販売単価が2,000円の商品は、品目B、品目Eの2商品がある。
で、イには、その内のどれを表示すればいいのか?

ウは販売単価が3,000円の集合だが、販売単価が3,000円の商品は、品目Cの1商品だけ。
ウには品目Cを表示すれば済むが、その後品目Gが追加され、その販売単価が3,000円だったら?

GROUP化クエリは、GROUP化したそのGROUP毎に1つにまとめてしまうため、その中身を全て表示することはできない。

GROUP BYを使う時、SELECT句に書ける列名は、GROUP BY句で指定した列名(集約キーという)だけである。

MySQLSQLiteでは、エラーとはならず通ってしまう。
では、上記のには何を表示するか、だが、実は、これといった決まりがない。

GROUP BY 部から省略したカラムがグループ内で一定していない場合は、この機能を使用しないでください。
サーバはいかなる値もグループから自由に戻すことができ、すべての値が同じでない限り、結果は不確定です。

11.11.3. 非常時フィールドとの GROUP BY および HAVING

つまり、

商品名,販売単価,数
品目A,1000,3

となることもあれば、

商品名,販売単価,数
品目D,1000,3

となることもあれば、

商品名,販売単価,数
品目F,1000,3

となることもあるということ。

参考:SQLアンチパターン 155ページ 第14章 アンビギュアスグループ(曖昧なグループ)

スポンサーリンク
SQLアンチパターン
Bill Karwin
オライリージャパン
売り上げランキング: 12,496

これは非常に危険であるので、エラーではじいてくれた方がいいかもしれない。

また、問題のないSQL文、

SELECT `販売価格`,COUNT(*)
FROM `商品一覧`
GROUP BY `販売価格`

で得られた結果

販売単価,数
1000,3
2000,2
3000,1

だが、この並び順はランダム。

販売単価,数
3000,1
2000,2
1000,3

となるかもしれないし、

販売単価,数
2000,2
1000,3
3000,1

となるかもしれない。

SQLアンチパターン
Bill Karwin
オライリージャパン
売り上げランキング: 12,496
スポンサーリンク



sha-bc@336×280

sha-bc@336×280


sha-bc@336×280

sha-bc@336×280

  関連記事

no image
悪質な 163data.com.cn を拒否する(.htaccess,拒否リスト)

スポンサーリンク あるサイトに対する、無駄なアクセスが多いのは分かっている。 放 …

Linuxの採用
SONYのデジタル一眼が動作緩慢(遅い)な理由 – Linuxの採用

スポンサーリンク SONYのデジタル一眼は、TLM(トランスルーセントミラー)を …

SSDとHDD_換装_CF-R6_C300(64GB)
Panasonic CF-R6の分解②(ハードディスクをSSDへ換装) CF-R7,CF-R8も同様

スポンサーリンク 熱杉流かつ遅杉流、Panasonic(旧松下)のノートパソコン …

ダンプ行を指定する箇所
[MySQL] テーブルのエクスポートで、レコード数の不一致が生じる問題 [phpMyAdmin,Dump all rows]

スポンサーリンク DB(MySQL)にある巨大なテーブルをローカルに保存したいと …

no image
LinuxのCUI→GUI化を考える

スポンサーリンク 昔に比べるとLinuxも随分簡単になり、GUIで操作できる部分 …

no image
CPU対決!激重SQL編!(Phenom X3 8400 vs Core i5 650)

スポンサーリンク 実行時間が70秒近くかかる激重クエリがある。 この実行に於ける …

E3110
DBサーバーのハードウェア換装(Debian7.4,MySQL5.5.35) Xeon E3110

スポンサーリンク 試験データベースサーバー(DBサーバー)を入れ替えた。 Deb …

no image
[解決]ローカル内の他の端末からMySQLに接続できない件[my.cnf,bind-address]

スポンサーリンク DebianにMySQLを入れてDBサーバーとし、ローカル環境 …

no image
Debian7.4でWEBサーバーを立てる(Apache,MySQL,PHP,phpMyAdmin,FTP)

スポンサーリンク Windows環境でもXAMPPを入れると環境が整うので(その …

no image
サーバー情報の表示内容(ServerTokens)変更 (Apache2.2.22 ,Debian7.4)

スポンサーリンク Apache/2.2.22 (Debian7.4) /etc/ …