• ベストアンサー

複数のテーブルに跨る集計

こんばんは。お世話になっております。 テーブル(member) id id_name name  1 takashi さんま 2 sayuri きゅうり 3 akemi  とまと テーブル(data) id date 2 07-1-20 3 07-1-20 2 07-1-20 1 07-1-21 2 07-1-21 3 07-1-21 以上のようなテーブルがあり、下記のように、テーブルdataのidをカウントし、多いもの順に結果を表示させたいのですが、このような場合のソースが分かりません。 結果 きゅうり 3件 とまと  2件 さんま  1件 似たような質問をされている方も過去に多くあるようですが、私のケースとどれが適しているかさえも分からず投函させていただきました。 お忙しい中恐縮ですが、説明のあるサイト、またはアドバイスなどご指導いただけたら幸いです。宜しくお願い致します。

  • MySQL
  • 回答数3
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
  • asx
  • ベストアンサー率50% (27/54)
回答No.2

#1です。 1点、前回書き込んだSQL文に間違いがありましたね。 「from member M, date D」は「from member M, data D」の間違えでした。(二つ目のテーブル名はdateではなくてdataでしたね。)紛らわしい間違えをしてしまってすみません。。 こちらを修正してもうまくいきませんか?(SQL文の文法エラー?望んでいた結果が出ない?) もし、表示する項目が、nameとカウント数以外にあるのでしたら、それも、group byで指定しないといけません。 例えば、idも表示する必要があるならば、 --------------------------------------------- select M.id, M.name, count(M.name) as count from member M, data D where M.id = D.id group by M.name, M.id order by count desc --------------------------------------------- となります。 inner joinを使用するならば、 --------------------------------------------- select M.id, M.name, count(M.name) as count from data D inner join member M on M.id = D.id group by M.name, M.id order by count desc --------------------------------------------- > 見慣れないDやMの意味が分からずにいる状況です。 「テーブル名 別名」と書くことで、そのSQL文でだけ有効なテーブルの別名を付けることができます。 sadachaさんが書かれたSQL文に、 > FROM data INNER JOIN member ON data.id = member.id とありますよね。 これを、dataテーブルを「D」、memberテーブルを「M」という別名を使った場合、 FROM data D INNER JOIN member M ON D.id = M.id という書き方ができます。 テーブル名が長かったりしたときに、いちいち、「<テーブル名>.<項目名>」と書いているとそれだけでSQL文が長くなってしまって見辛くなってしまいますので、そういうときに使ったりします。 もちろん使わなきゃいけないわけでも、一般的に使うものでもなく、好みなので、別名をつけなくても問題ないですよ。 別名を使わないなら、最初に書いたSQL文は、 --------------------------------------------- select member.id, member.name, count(member.name) as count from member, data where member.id = data.id group by member.name, member.id order by count desc --------------------------------------------- となります。 それから、 > WHERE category = '4001' OR category = '4002' OR category = '4003' OR category = '4004' OR category = '4005' OR category = '4006' この部分ですが、「categoryが4001,4002,4003,4004,4005,4006のいずれかの場合」という条件指定ですよね。 これは、in句というものを使うことができます。 「項目名 in (値1,値2,値3)」と記述することで、項目名の値がが、値1か値2か値3の場合、という意味になります。 ですので、「category in (4001, 4002, 4003, 4004, 4005, 4006)」とすることができます。 うまくいかないようでしら、どんなエラーが表示されるか(もしくはどんな結果が出てしまうか)を教えてください。

sadacha
質問者

お礼

asx様 早速のお返事を有難う御座います。 どれも詳細なご説明、本当に有難い気持ちで一杯です。非常に勉強になりました。 そこで2-3改めて質問なのですが、 結果 きゅうり 3件 1位 とまと  2件 2位 さんま  1件 3位 と、件数の取得(count)および、順位を表示させるのはどうしたらいいのでしょうか? (名前は順に表示させることが出来ました!) 勉強不足とはいえ知らない事が多すぎると、改めて知らさせる思いで一杯ですが、引き続きアドバイス頂ければ幸いです。宜しくお願い致します。

sadacha
質問者

補足

asx様 お世話になっております。 件数表示までは表示させる事ができたのですが、順位表示(1位、2位、…)までは未だ出来ずにおります。 色々と調べてはいるのですが、中には「出来ない」というような記載があったりで、「どうしたものか?」と頭を悩ませております。 引き続きアドバイス頂けたら幸いです。宜しくお願い致します。

その他の回答 (2)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.3

ランク付けについてはPHPを使っているなら基本的にはPHP側でやった方が 効率的だと思います。 どうしてもSQLでやるというなら以下のように変数を用意して加算していく 方法が妥当でしょう。この場合変数をインクリメントしていますので SETを使って宣言しておかないといけません。 こんな感じです。 SET @RANK=0; SELECT `M`.`id` ,`M`.`name` ,@RANK:=@RANK+1 AS `rank` ,COUNT(*) as `count` FROM data AS `D` INNER JOIN `member` AS `M` USING (`id`) GROUP BY `M`.`id` ORDER BY `count` DESC; 単純に@RANKを加算すると当然同点の場合でも順位がついてしまいます。 それが困る場合は上のレコードのカウント値を保存しておき、 オフセットしてやるとよいでしょう。 こんな感じです。 SET @RANK=0,@COUNT=0,@OFFSET=0; SELECT `M`.`id` ,`M`.`name` ,(@RANK:=@RANK+1)+(@OFFSET:=IF(@COUNT=count(*),@OFFSET-1,0)) AS `rank` ,@COUNT:= COUNT(*) as `count` FROM data AS `D` INNER JOIN `member` AS `M` USING (`id`) GROUP BY `M`.`id` ORDER BY `count` DESC;

sadacha
質問者

お礼

yambejp様 こんばんは。いつもお世話になっております。 ご挨拶が遅れて申し訳ありません。 後になって、当初の質問からズレテしまったこともあり、一旦「解決」とまで考えていましたが、yambejp様のいう『基本的にはPHP側で』ということに気付かされ、あれこれやっているうちにお返事が遅くなってしまいました。すみません。 時間は掛かってしまったものの、PHP側でやると、思いのほか簡単に出来るんですね。今回は(申し訳ないな・・と思いつつ)、PHPにて対処したいと思いますが、yambejp様からの貴重なアドバイスも今後に取り入れたいと思っております。 感謝しております。有難う御座いました!

  • asx
  • ベストアンサー率50% (27/54)
回答No.1

select M.name, count(M.name) as count from member M, date D where M.id = D.id group by M.name order by count desc これでご希望の結果が出ると思いますよ。 テーブルの結合については判ることを前提にちょっとだけ解説しておきます。 ---------- きゅうり 3件 とまと  2件 さんま  1件 ---------- これは、つまり、名前毎に件数を表示させたいのですよね。 この「名前毎」というのがポイントです。 「○○毎」とまとめたいものを、group byで指定します。 表示順を変えたい場合は、order byを使用します。 order by 項目名 で使用することができますが、この場合は、指定した項目名の数字が小さい順に表示されます。 数字の大きい順に表示したい場合は、 order by 項目名 desc と記述します。 Googleでgroup byやorder byで検索してみると、いろいろ出てくると思います。

sadacha
質問者

お礼

asx様 はじめまして、こんばんば。早速の回答を有難う御座います! ご丁寧に解説していただいているにも関わらず、お恥ずかしいながら上手く設定する事が出来ません。 当初、カウントすることが頭になかったときに書いたコードは下記のようなものですが、お教えいただいたコードに書き換えても、見慣れないDやMの意味が分からずにいる状況です。 お忙しい中恐縮ですが、今一度ご指導のほど宜しくお願い致します。 ※質問時には省略していますが、検索結果の条件も記載しています。 $sql= "select * FROM data INNER JOIN member ON data.id = member.id WHERE category = '4001' OR category = '4002' OR category = '4003' OR category = '4004' OR category = '4005' OR category = '4006' limit 0,10 ";

関連するQ&A

  • 複数のテーブルに跨る集計その2

    こんにちは。お世話になっております。 http://oshiete1.goo.ne.jp/qa2684315.html 昨日、上記ページより投函させていただきましたが、その時は解決できたものの、その後の新たなソースの追加で上記ページにある、検索結果表示にある、各々の「件数表示」が出来なくなってしまいました。 当初は単に追加したソースが邪魔してる?などという思いから、色々と設定を変えているものの上手く行かず、現在なんとか件数表示を表示する事は出来たものの、繰返処理(while)の中に新たに、 $id = $row['id']; $sql = "select id FROM data WHERE id = '$id'"; $result = mysql_query($sql); $rows = mysql_num_rows($result); echo $rows; なんて、入れることで対処出来ましたが、この対処法に自信がなく、改めて諸先輩方々にヒントだけでもご指導いただければと投函させて頂きました。 お忙しい中恐縮ですが宜しくお願い致します。 ※通常の?検索ソースは上記ページでご教授いただいた select M.id, M.name, count(M.name) as count from data D inner join member M on M.id = D.id group by M.name, M.id order by count desc を参考にさせていただいております。

    • ベストアンサー
    • MySQL
  • 複数テーブルの集計

    お世話になっています。 複数テーブルの集計がわからないので質問させてください。 テーブル3のItem1~4にはテーブル2のItemIDを登録します。 エリア毎の参加人数をcsvデータを出力させたいです。 テーブル3においてテーブル2のItemIDが4つあるので、一人に対して4行必要なのかと思いましたが、テーブルの変更ができません。 テーブルの結合まではできましたがその後ができません。 テーブルの変更ができませんので、結合するためにテーブル2の構造とデータが同じテーブルを他に3つ作成しています。 どうぞよろしくお願いします。 テーブル1 AreaID   AreaName --------------------- 1 北海道 2 東北 3 関東 4 北陸 テーブル2 ItemID ItemName --------------------- 1 自由形50 2 自由形100 3 背泳ぎ50 4 平泳ぎ50 テーブル3 ID AreaID   Name  Item1   Item2  Item3 Item4 --------------------------------------------------------- 1   2    鈴木    2    1    4     3 2   3    佐藤    1    null   3    null 3   1    田中    1    2    null   null 4   2    伊藤    3    null   2    4  5   3    川村    null   2    3    null 「集計結果」       参加人数 自由形50 自由形100 背泳ぎ50 平泳ぎ50 --------------------------------------------------------------- 北海道    1     1     1     0     0  東北     2     1     2     2     2   関東     2     1     1     2     0   北陸     0     0     0     0     0

    • ベストアンサー
    • MySQL
  • 複数テーブルでの件数検索について

    Oracle上の2つのテーブルからの条件でマッチする件数をSQLで作成しています。 内容としては、テーブルAの区分=1 かつ テーブルBの種別がスペースの件数です。 テーブルAの該当するデータは10件中3件、テーブルBの該当するデータは50件中15件で、本来両方がマッチするのは2件です。 SELECT COUNT(*) FROM テーブルA,テーブルB WHERE テーブルA.区分 = '1' AND テーブルB.種別 = ' ' ; 上記のSQL文で件数をカウントしたのですが、どうも結果では30件とカウントされてしまいます。 なんとか2件として結果を出したく、参考資料を調べているところなのですが、今のところ参考になる文献が見つからず悩んでます。もし簡単にカウントできるSQLがあったり、分かる方がいれば手助けして頂きたいと思い、今回投稿しますのでご教授賜りたく思います。よろしくお願いします。

  • 複数テーブルの結合

    テーブルA  a_id id a_data a_date ----------- テーブルB id b_data b_date テーブルC id c_data c_date ----------- テーブルAとテーブルBは「id」がキーで1:N(Nは0も含む) テーブルAとテーブルCは「id」がキーで1:N(Nは0も含む) このような3のテーブルで a_idを検索キーにして次のフィールドのデータを抽出したいのですが。。。 ※テーブルCのc_dateを降順で先頭の1レコードのみ ※テーブルBのidをカウントする selectの結果(イメージ) id a_data a_date count(B.id) c_date ------------------------------------- 001 AAAA 2007/02/01 20 2007/02/14 005 BBBB 2007/02/02 0 2007/02/10 006 CCCC 2007/02/02 0 2007/01/08 003 DDDD 2007/02/01 100 002 EEEE 2007/02/01 9 004 FFFF 2007/02/01 0 よろしくお願いします

  • データ件数を取得したい

    こんばんは。お世話になっております。 http://oshiete1.goo.ne.jp/qa2684315.html 先日、カテゴリMySQLにおいて(上記ページ)、下記のような結果を返すための質問をさせていただき、当初は出来たものの、込み入ったソースが故に、各件数の取得が出来なくなってしまいました。 結果 きゅうり 3件 とまと  2件 さんま  1件 本来であれば、全てのソースを提示すべきところでしょうが、文字数制限もありそれが出来ず、また、当初出来たというのも、「たまたま出来た」という程度だったのかなどと思うようになり、改めて考え方というものをご教授いただきたく投函させていただきました。 ちなみに(お恥ずかしいのですが。汗)、当初出来たというのは、 echo $row[2]; で件数を取得を取得する事が出来ました。 お忙しい中恐縮ですが、ヒントだけでも頂戴出来れば幸いです。 宜しくお願い致します。

    • ベストアンサー
    • PHP
  • 複数テーブルをまとめてソート

    たとえば次のような、都道府県ごとのテーブルがあり、 ID、名前、得点の列があるとします。 テーブル1(テーブル名:tokyo) ID NAME SCORE 1 yamada 89 2 tanaka 45 テーブル2(テーブル名:osaka) ID NAME SCORE 1 sato 65 2 suzuki 22 これらのテーブルをまとめて、全国で得点が上位順に並べたいと 思っております。また、結果にはどのテーブルに所属するものかを 判別する列を追加したいのですが、どういう文を記述したらよいのでしょうか? 望みの結果は次のようなものです。 NAME SCORE TABLE_NAME yamada 89 tokyo sato 65 osaka tanaka 45 tokyo suzuki 22 osaka よろしくお願いします。

    • ベストアンサー
    • MySQL
  • 複数テーブルの集計その2

    お世話になります。 先日テーブルの集計について教えていただき、下記集計結果を取得することができたのですが、 新たに自由形50~平泳ぎ50までの合計を追加したいのです。(一人で4種目参加する場合は4と数える) テーブル1 AreaID   AreaName --------------------- 1 北海道 2 東北 テーブル3 ID AreaID   Name  Item1   Item2  Item3 Item4 --------------------------------------------------------- 1   2    鈴木    2    1    4     3 2   1    田中    1    2    null   null 3   2    伊藤    3    null   2    4  「集計結果」       参加人数 自由形50 自由形100 背泳ぎ50 平泳ぎ50  追加部分 --------------------------------------------------------------- 北海道     1     1       1      0      0       2 東北      2     1       2      2      2       7   $sql="select AreaName, count(distinct ID) 参加人数, count(case when Item=1 then 1 else null end) as 自由形50, ・・・略 from t1 as x left join (select ID,AreaID,1 as Item from t3 where Item1=1 or Item2=1 or Item3=1 or Item4=1 union all select ID,AreaID,2 as Item from t3 where Item1=2 or Item2=2 or Item3=2 or Item4=2 ) as y on x.AreaID=y.AreaID group by AreaName order by x.AreaID というようにおしえていただきました。 null以外を取得するSQLをカウントとselectに追加すればいいのかと思い試したのですが期待した値を取得できません。 count(case when Item=AAA then 1 else null end) as abc,と union all select ID,AreaID,AAA as Item from テーブル3 where ItemID1<>'' or ItemID2<>'' or ItemID3<>'' or ItemID4<>'' or (ItemID1<>'' and ItemID2<>'') ・・・ バージョンはMySQL4.1.18です。 よろしくお願い致します。

    • ベストアンサー
    • MySQL
  • 複数テーブルからのカウント集計

    初めて、投稿させて頂きます。 カルテテーブルに登録されたデータより、スタッフごとにどのサービスを何回対応したかを出力したいのですが、経験が浅く考え込んでいます。 また、日付の制限も指定したいです。 何卒、アドバイスをお願い致します。 MySQL 4.0.24-standardを使用しています。 カルテテーブル(chart_table) --------------------------------------- staff | date | service1 | service2 | service3 | service4 | 1 2007-01-27 1 2 0 0 3 2007-02-07 0 0 3 4 2 2007-03-04 1 0 3 4 スタッフテーブル(staff_table) --------------------------------------- no | id | 1 佐藤 2 鈴木 3 田中 サービステーブル(service_table) --------------------------------------- no | name | 1 サービスA 2 サービスB 3 サービスC 4 サービスD 結果(2007-01 ~ 2007-03) ---------------------------------------       佐藤 | 鈴木 | 田中 | サービスA 1 1 0 サービスB 1 0 0 サービスC 0 1 1 サービスD 0 1 1

    • ベストアンサー
    • MySQL
  • 複数テーブルの結合

    マスターテーブル1つと、子テーブルが複数存在して子テーブルにはマスターテーブルのidを格納するフィールドがあり参照しなくなったときにはそのidを消去するといったデータベースがあったときにマスターIDごとに子テーブルのどれか1つでも参照していればカウントするみたいなSQLをつくりたいんですが select count(m.id) from master m inner join a on m.id = a.m_id inner join b on m.id = b.m_id inner join c on m.id = c.m_id group by m.id みたいなSQLだとAにデータが存在しなければB以降に存在しても期待した結果が出力されません。A、B、Cいずれかのm_idとマスター側のIDが等しければカウントするという出力をするためにはどのように書けばいいんでしょうか。 わかりづらい説明で申し訳ありませんがよろしくお願いします。

    • ベストアンサー
    • MySQL
  • 複数テーブルの削除

    お世話になります。 うまい資料が見つからなかったので質問させてください。 例えば、下記のようなテーブルが3つあったとします。 <table1> id name date <table2> id tel <table3> id etc name,date,tel,etcは同タイミングで一括に登録され、3テーブルともに共通のidで保存されます。 この時、table1のdate(日付が入ります)が30日以上経過しているデータについて、いずれのテーブルからも削除したいと思っています。 こんな場合、どんなSQL文を書けば良いのでしょうか? お分かりになる方、何卒よろしくお願いしますm(_ _)m

    • ベストアンサー
    • MySQL