MySQLの集約関数について質問です!


テーブル1
C1 F2
1  1
2  1
3  2
1  2
2  3

下記のSQL文で実行しています。
※変数Hに1を代入する
$H = 1;

$sql = "";
$sql .= "select F2, count(*) as cnt from テーブル1";
$sql .= " WHERE C1 = '{$H}'";
$sql .= " group by F2";
$rsc = mysql_query($sql);

結果は、
1 = 1コ
2 = 1コ
になります。
このテーブルにフィールドを二つ追加して、

テーブル1
C1 F2 C3 F4
1  1  2  4
2  1  1  3
3  2  1  1
1  2  3  1
2  3  4  2

今度は変数Hが1だった場合にC1とC3を参照してとぢらかが一致したもののFのカテゴリの数を集約したいのですが、上手く説明できません。
頭の中では下記のような感じです。

C1 F2
1  1
2  1
3  2
1  2
2  3
 
C3 F4
2  4
1  3
1  1
3  1
4  2

結果
1 = 2コ
2 = 1コ
3 = 1コ

上記の結果を出したいのですが、この説明でお分かりの方は、教えて下さい!

回答の条件
  • 1人50回まで
  • 登録:2006/11/09 19:53:23
  • 終了:2006/11/16 19:55:03

回答(14件)

id:b-wind No.1

b-wind回答回数3344ベストアンサー獲得回数4402006/11/09 20:14:18

ポイント14pt

問題は分かるのですが、テーブル設計に問題があるような気が。

MySQL5 ならサブクエリが使えるのでやりやすいかもしれません。

SELECT F,sum(cnt) FROM
(
 SELECT F2 AS F,count(*) AS cnt FROM テーブル1
   WHERE C1 = '$H'
 UNION
 SELECT F4 AS F,count(*) AS cnt FROM テーブル1
   WHERE C3 = '$H'
) AS table_all
  GROUP BY F;

試していないので間違っているかもしれませんが。

id:black_kenchan

説明不足ですいません。文字数がオーバーしてしまいあまりかけませんでした。

商品の管理なのですが、CがメインカテゴリでFがサブカテゴリです。

一つの商品に二つの属性を持たせたくてこのような感じになっています。

上記のSQL文なのですが、MySQL4でも可能でしょか?

2006/11/09 20:21:21
id:b-wind No.2

b-wind回答回数3344ベストアンサー獲得回数4402006/11/09 20:40:21

ポイント14pt

前の回答は、MySQL4.1 以上で可能、MySQL4.0以下だと不可能のはず。


CREATE TEMPORARY TABLE テーブル_tmp
 ( F text, cnt int )
 SELECT F2 AS F,count(*) AS cnt FROM テーブル1
   WHERE C1 = '$H'
 UNION
 SELECT F4 AS F,count(*) AS cnt FROM テーブル1
   WHERE C3 = '$H';
SELECT F,sum(cnt) FROM テーブル_tmp GROUP BY F;

ならどのバージョンでもいけると思います。

id:black_kenchan

両方試したのですが、出来ないッス!

なんででしょうか?

2006/11/09 22:24:27
id:b-wind No.3

b-wind回答回数3344ベストアンサー獲得回数4402006/11/10 01:08:10

ポイント14pt

なんででしょうね。

エラーメッセージは出ていると思うので、提示していただけますか?

id:black_kenchan

あれから、色々試してるのですがだんだん近づいてきて下記のSQL文だとかなり近いところまで行きました。

※WHEREは省略しています。

SELECT F2 AS F, count(*) as cnt FROM テーブル1 group by F UNION ALL SELECT F4 AS F, count(*) as cnt FROM テーブル1 group by F

現在は、

1 = 2コ

2 = 1コ

3 = 1コ

1 = 2コ

2 = 1コ

3 = 1コ

見たいな感じでC1とC3の結果が繰り返されているのでまとめるだけなのですが・・・・

2006/11/10 01:24:55
id:b-wind No.4

b-wind回答回数3344ベストアンサー獲得回数4402006/11/10 01:30:04

ポイント14pt

その状態からさらにまとめるには、サブクエリとして扱い再度 GROUP 化するしか無いと思います。

ただし、それは MySQL4.1 からの機能なので、それ以前のバージョンではテンポラリテーブルを使う事で代用します。

http://dev.mysql.com/doc/refman/4.1/ja/create-table.html

id:black_kenchan

難しくて分からなかったです・・・

回答1の答えなのですが、試しに

SELECT F2 AS F,count(*) AS cnt FROM テーブル1

のみでやったのですがこれだけもエラーでした・・COUNTの使い方がいけないかも知れません。

逆にそこだけ直せば出来るかも・・・

何か良い方法は無いでしょうか?

2006/11/10 01:40:06
id:b-wind No.5

b-wind回答回数3344ベストアンサー獲得回数4402006/11/10 02:13:30

ポイント14pt

集約関数は GROUP BY が無いと使えません。

SELECT F2 AS F,count(*) AS cnt FROM テーブル1 GROUP BY F2;

でないと無理。

という事で1でのの解答は間違っていますね。惑わせて閉まったようですいません。

SELECT F,sum(cnt) FROM
(
 SELECT F2 AS F,count(*) AS cnt FROM テーブル1
   WHERE C1 = '$H'
   GROUP BY F2
 UNION
 SELECT F4 AS F,count(*) AS cnt FROM テーブル1
   WHERE C3 = '$H'
   GROUP BY F4
) AS table_all
  GROUP BY F;

がおそらく正しい。


結局 MySQL のバージョンはなんなんでしょうか?

SELECT VERSION();

で調べられます。

http://dev.mysql.com/doc/refman/4.1/ja/miscellaneous-functions.h...

id:black_kenchan

バージョンは、4.0.0みたいです。

試したのですが、やっぱり出来ません。

エラーメッセージは

Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource

こんな感じでした。

なんで、できないのですかね・・・

2006/11/10 02:26:41
id:b-wind No.6

b-wind回答回数3344ベストアンサー獲得回数4402006/11/10 02:43:52

ポイント14pt

4.0.0 だとまだだいぶバグも残っているので、せめて 4.0.27 まではあげた方が良いと思います。


4.0 系列ではサブクエリはサポートされていないので、先ほどの方法は使えません。

q#2 で回答した方向で考えることになります。

プログラムから実行する場合、

CREATE TEMPORARY TABLE テーブル_tmp
 ( F text, cnt int )
 SELECT F2 AS F,count(*) AS cnt FROM テーブル1
   WHERE C1 = '$H'
   GROUP BY F2
 UNION
 SELECT F4 AS F,count(*) AS cnt FROM テーブル1
   WHERE C3 = '$H';
   GROUP BY F4

でテンポラリテーブルを作成し、その後

SELECT F,sum(cnt) FROM テーブル_tmp GROUP BY F;

で作成したテーブルから再度集計する事になります。

id:black_kenchan

出来ません・・・

PHPで表示しようとしているのですが、コロンを打つところが間違えているのですかね・・・

2006/11/10 03:15:44
id:b-wind No.7

b-wind回答回数3344ベストアンサー獲得回数4402006/11/10 03:18:20

ポイント14pt

間違えてますね。

ただしくは、

CREATE TEMPORARY TABLE テーブル_tmp
 ( F text, cnt int )
 SELECT F2 AS F,count(*) AS cnt FROM テーブル1
   WHERE C1 = '$H'
   GROUP BY F2
 UNION
 SELECT F4 AS F,count(*) AS cnt FROM テーブル1
   WHERE C3 = '$H'
   GROUP BY F4;

になります。


できればいきなり PHP でやらずに、mysql コマンドなり、phpMyAdmin 等の管理ツールなりで確認した方が良いと思われますが。

id:black_kenchan

すいません・・・

やっぱり出来ないッス・・・

今度はちゃんとmysql コマンドで試みたのですが、なぜか出来ません。

2006/11/10 03:34:26
id:b-wind No.8

b-wind回答回数3344ベストアンサー獲得回数4402006/11/10 12:37:09

ポイント14pt

正確にどのクエリを投げてどのようなエラーが帰ってきたのか教えてください。

こちらではすぐに環境を用意できませんので。

id:black_kenchan

あれから色々試して分かったことは、

CREATE TEMPORARY TABLE テーブル_tmp

( F text, cnt int )

の後にセミコロンが必要みたいです。

CREATE TEMPORARY TABLE テーブル_tmp

( F text, cnt int );

SELECT F2 AS F,count(*) AS cnt FROM テーブル1

WHERE C1 = '$H'

GROUP BY F2

UNION

SELECT F4 AS F,count(*) AS cnt FROM テーブル1

WHERE C3 = '$H'

GROUP BY F4;

上記だけのSQL文だけでやると正常に出るのですが、

SELECT F,sum(cnt) FROM テーブル_tmp GROUP BY F;

を加えると

Table 'テーブル_tmp' already exists Query was empty

とエラーが出てきてしまいます。

2006/11/10 13:52:19
id:b-wind No.9

b-wind回答回数3344ベストアンサー獲得回数4402006/11/10 15:31:05

ポイント13pt

提示した SQL はテンポラリテーブルを作成し、その中にクエリの内容をインサートする、というものです。

セミコロンで分ければ別の意味になります。


F text の方が一致していないかもしれませんね。

F2 および F4 の型を教えてください。

id:black_kenchan

全てINTです。

2006/11/10 15:46:59
id:b-wind No.10

b-wind回答回数3344ベストアンサー獲得回数4402006/11/10 16:04:34

ポイント13pt

では、

CREATE TEMPORARY TABLE テーブル_tmp
 ( F int, cnt int )
 SELECT F2 AS F,count(*) AS cnt FROM テーブル1
   WHERE C1 = 1
   GROUP BY F2
 UNION
 SELECT F4 AS F,count(*) AS cnt FROM テーブル1
   WHERE C3 = 1
   GROUP BY F4;

を実行してみてください。

テスト用に $H の値は1を明示してあります。

id:black_kenchan

やはり

CREATE TEMPORARY TABLE テーブル_tmp

( F int, cnt int )

の後にセミコロンをつけないと下記のエラーになります。

Duplicate column name 'F'

2006/11/10 16:24:20
id:b-wind No.11

b-wind回答回数3344ベストアンサー獲得回数4402006/11/10 16:27:29

ポイント13pt

なるほど。ではこれでどうでしょう?

CREATE TEMPORARY TABLE テーブル_tmp
 ( F int, cnt int )
 SELECT F2,count(*) FROM テーブル1
   WHERE C1 = 1
   GROUP BY F2
 UNION
 SELECT F4,count(*) FROM テーブル1
   WHERE C3 = 1
   GROUP BY F4;
id:black_kenchan

今度は、

Duplicate column name 'cnt'

上記のエラーが・・・

無理なんでしょうかね・・・

2006/11/10 17:07:14
id:b-wind No.12

b-wind回答回数3344ベストアンサー獲得回数4402006/11/10 18:43:28

ポイント13pt

あれ、cnt も使わないようにしたはずなんですが。

とりあえず、どこかやり方を失敗しているだけで絶対に可能なので安心してください。


手順を4つに分けましょう。

テンポラリテーブルの作成。

CREATE TEMPORARY TABLE テーブル_tmp ( F int, cnt int );

テンポラリテーブルへのデータ投入1。

INSERT INTO テーブル_tmp ( F, cnt )
 SELECT F2,count(*) FROM テーブル1
   WHERE C1 = 1
   GROUP BY F2;

テンポラリテーブルへのデータ投入2。

INSERT INTO テーブル_tmp ( F, cnt )
 SELECT F4,count(*) FROM テーブル1
   WHERE C3 = 1
   GROUP BY F4;

データの集計処理

SELECT F,sum(cnt) FROM テーブル_tmp GROUP BY F;

これを順に実行し、どこかでエラーが出たらそのメッセージを正確に教えてください。

id:black_kenchan

やってみたのですが、もう少しっぽいです。

エラーは、

#1064 - You have an error in your SQL syntax near '; ' at line 2

こんな感じだったのですが、sumの関数が問題あるような感じです。

2006/11/10 19:02:35
id:b-wind No.13

b-wind回答回数3344ベストアンサー獲得回数4402006/11/10 19:09:53

ポイント13pt

では、確認のため

SELECT F,cnt FROM テーブル_tmp;
SELECT F,count(*) FROM テーブル_tmp GROUP BY F;

の両SQLを実行し、表示される実行結果を教えてください。

id:black_kenchan

いろいろ試したのですが、前回と同じエラーでした。

すいません・・・

2006/11/10 19:57:25
id:b-wind No.14

b-wind回答回数3344ベストアンサー獲得回数4402006/11/10 20:29:42

ポイント13pt

では、

SHOW TABLES;

と実行してでてくる結果の中に テーブル_tmp があるか確認してください。

無い様であれば、CREATE ... からやり直してみてください。

id:black_kenchan

色々試したのですが、やっぱり駄目でした。

今回のエラーメッセージは、

#1146 - Table 'データベース名' doesn't exist

でした。

もう諦めようと思います・・・

2006/11/10 22:34:06

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません