MySQL条件での絞込みで問題発生

このQ&Aのポイント
  • MySQLの条件での絞込みが思うようにいかない問題が発生しました。
  • 特に、結果の「cat1」「cat2」に他のカテゴリーの値が入らなくなる現象が発生しています。
  • 絞り込みの条件を適切に設定し、全てのカテゴリーの値が含まれた結果を取得する方法を教えてください。
回答を見る
  • ベストアンサー

MySQL 条件での絞込みがうまくいきません

下記の質問をさせていただき、解決いたしましたが、それに関連して新たなご質問です。 http://okwave.jp/qa/q8830319.html 上記質問内容は、 以下のようなデータから、「結果」のような形でデータを取り出したいというもので、「いただいたご回答」の形で一旦解決しました。 usr テーブル +--------+------+ | usr_id | name | +--------+------+ | 1 | 太郎 | | 2 | 二郎 | | 3 | 花子 | +--------+------+ usr_trm テーブル +--------+--------+ | usr_id | trm_id | +--------+--------+ | 1 | 1 | | 1 | 3 | | 1 | 4 | | 2 | 1 | | 2 | 2 | | 2 | 3 | | 3 | 2 | +--------+--------+ cat テーブル +--------+------+ | cat_id | name | +--------+------+ | 1 | 性別 | | 2 | 部署 | +--------+------+ trm テーブル +--------+--------+------+ | trm_id | cat_id | name | +--------+--------+------+ | 1 | 1 | 男性 | | 2 | 1 | 女性 | | 3 | 2 | 総務 | | 4 | 2 | 経理 | +--------+--------+------+ 結果 +--------+------+------+------+ | usr_id | name | cat1 | cat2 | +--------+------+------+------+ | 1 | 太郎 | 1 | 3,4 | | 2 | 二郎 | 1,2 | 3 | | 3 | 花子 | 2 |   | +--------+------+----- +------+ いただいたご回答 select t1.usr_id,t3.name ,group_concat(if(cat_id=1,t1.trm_id,null)) as cat1 ,group_concat(if(cat_id=2,t1.trm_id,null)) as cat2 from usr_trm as t1 inner join trm as t2 on t1.trm_id=t2.trm_id inner join usr as t3 on t1.usr_id=t3.usr_id group by usr_id さらにそこから、例えば「総務に所属する人をランダムにn件」という形で絞り込もうと思い、 WHERE t2.trm_id=3 と ORDER BY RAND() LIMIT 10 を追加したところ、条件通り抽出はされるのですが、結果の「cat1」「cat2」に他のカテゴリーの値が入らなくなりました。 WHERE t2.trm_id=3 を消すと「cat1」と「cat2」に値が入ってきます。 「cat1」と「cat2」に全ての値が入った状態で絞込をするために、どのようにすればよいかわかりません。 アドバイスをいただけると幸いです。

  • sr-ki
  • お礼率68% (43/63)
  • MySQL
  • 回答数1
  • ありがとう数8

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

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

この場合はusr_trmでユーザーごとのtrmを確認しないといけないのでは? select t1.usr_id,t3.name ,group_concat(if(t2.cat_id=1,t1.trm_id,null)) as cat1 ,group_concat(if(t2.cat_id=2,t1.trm_id,null)) as cat2 from usr_trm as t1 inner join trm as t2 on t1.trm_id=t2.trm_id inner join usr as t3 on t1.usr_id=t3.usr_id inner join usr_trm as t4 on t4.usr_id=t1.usr_id and t4.trm_id=3 group by usr_id order by rand() limit 10; >総務に所属する人をランダムにn件 便利な機能だとは思いますが、SQLは明確な結果を得るための手段なので 不確実なrand処理を選ぶのは、個人的にはお勧めいたしかねます

sr-ki
質問者

お礼

ご回答ありがとうございます! まだ途中なのですが、ご回答を参考にさせていただき何とかうまく実装できそうです。 rand処理の件も助言いただきありがとうございます。 勉強させていただきました!

関連するQ&A

  • MySQL この場合どう書けばよいでしょうか?

    以下のようなデータがあります。 このデータから最後の「結果」のような形でデータを取り出したい場合、どのようにすればよいでしょうか? cat1とcat2を分けない形はgroup_concatを使ってできたのですが、カテゴリーごとに分けて取得したいです。 usr テーブル +--------+------+ | usr_id | name | +--------+------+ | 1 | 太郎 | | 2 | 二郎 | | 3 | 花子 | +--------+------+ usr_trm テーブル +--------+--------+ | usr_id | trm_id | +--------+--------+ | 1 | 1 | | 1 | 3 | | 1 | 4 | | 2 | 1 | | 2 | 2 | | 2 | 3 | | 3 | 2 | +--------+--------+ cat テーブル +--------+------+ | cat_id | name | +--------+------+ | 1 | 性別 | | 2 | 部署 | +--------+------+ trm テーブル +--------+--------+------+ | trm_id | cat_id | name | +--------+--------+------+ | 1 | 1 | 男性 | | 2 | 1 | 女性 | | 3 | 2 | 総務 | | 4 | 2 | 経理 | +--------+--------+------+ 結果 +--------+------+------+------+ | usr_id | name | cat1 | cat2 | +--------+------+------+------+ | 1 | 太郎 | 1 | 3,4 | | 2 | 二郎 | 1,2 | 3 | | 3 | 花子 | 2 |   | +--------+------+----- +------+

    • ベストアンサー
    • MySQL
  • 文字検索、列をまとめたい

    以下のようなテーブルで「test_id」ごとに文字列(contents)をまとめたいのです。 [テーブル1] test_id | name 1 山田 2 佐藤 3 鈴木 [テーブル2] id | test_id | contents 1 1 東京は晴れです。 2 1 電車です。 3 2 埼玉は晴れです。 4 3 電車です。 検索処理でテーブル1と2を結合しの「name」を表示します。 contentsが「東京」「電車」でand検索をすると0件になり、or検索をすると3件(名前は2人)ヒットするのですが、 「東京」「電車」としたときtest_idの「1」をヒットさせたいのです。 test_idをgroup byでsum(数値)のように文字列を指定するには どのようにすればいいのでしょうか。concatを使ってみたのですが、 (contentsのみを指定したから?)結果は得られず、わかりませんでした。 $sql="SELECT id,test_id,concat(contents), FROM テーブル1 as t1 left join テーブル2 as t2 on t1.test_id=t2.test_id where $where group by t2.Itest_id"; MySQL:4.0.27です。 よろしくお願いします。

  • 2つのSQL文で結果に差違が発生する

    私の知識ではお手上げのため、ご教授願いたいのですが、 下記のようなテーブルが仮にあったとして、レコードがそれぞれいくつか入っています。 【itemsテーブル】   id・・・・・連番   cat_id・・・category.id   price ・・・価格   max_num ・・セット数   date・・・・発売日 【categioryテーブル】   id・・・・・連番   cat_name・・カテゴリ名 【orderテーブル】   id・・・・・連番   item_id ・・items.id   paid_price・支払価格 以下の2つのSQL文を実行させた場合、「total_price」の値に違いは発生しますか? 【SQL文 A】----------------------------- SELECT items.cat_id, `category`.`cat_name`, SUM(`items`.`price` * `items`.`max_num`) AS `total_price`, SUM(IF(`order`.`paid_price` > 0, `order`.`paid_price`, 0)) AS `total_paid`, SUM(IF(`order`.`paid_price` = 0 , `items`.`price`, 0)) AS `not_payment` FROM `items` INNER JOIN `category` ON (`items`.`cat_id` = `category`.`id`) INNER JOIN `order` ON (`items`.`id` = `order`.`item_id`) WHERE DATE_FORMAT(`items`.`date`, '%Y%m') = 201511 GROUP BY `items`.`cat_id` ORDER BY `items`.`cat_id` ASC ------------------------------------ 【SQL文 B】----------------------------- SELECT items.cat_id, `category`.`cat_name`, SUM(`items`.`price` * `items`.`max_num`) AS `total_price` FROM `items` INNER JOIN `category` ON (`items`.`cat_id` = `category`.`id`) WHERE AND DATE_FORMAT(`items`.`date`, '%Y%m') = 201511 GROUP BY `items`.`cat_id` ORDER BY `items`.`cat_id` ASC ------------------------------------ こちらで上記と同じようなSQL文を実行すると、Bで出てほしい値がAでは出てこないのです。 Aの場合は「WHERE DATE_FORMAT(`items`.`date`, '%Y%m') = 201511」が抽出条件として実行されていないような感じです。 すべてのレコードの「SUM(`items`.`price` * `items`.`max_num`) AS `total_price`」が計算されています。 Bだけで実行すればちゃんとほしい値が返ってきます。 何か間違っていますか?

    • ベストアンサー
    • MySQL
  • アクセスではうまく行くのにMYSQLではうまくいきません。

    いつもありがとうございます。初心者です。どうか教えて下さい。 テーブル area フィールド area_id, area_name テーブル pref フィールド pref_id, pref_name, area_id テーブル city フィールド city_id, city_name, pref_id というように3つのテーブルがあり、それぞれarea_id,pref_id,city_id を主キーにして 結合して表示したいのですが、エラーになります。 SQL文は次のように書きました。 SELECT area.area_id, area.area_name, pref.pref_id, pref.ken_name, city.city_id, city.pref_id FROM area INNER JOIN (pref INNER JOIN city ON pref.pref_id = city.pref_id) ON area.area_id = pref.area_id するとエラーメッセージで #1064 - You have an error in your SQL syntax near '(pref INNER JOIN city ON pref.pref_id = city.pref_id) ON area.area_id = pref.are' at line 2 のように表示されます。 マイクロソフトのアクセスですると問題なく表示されるのですが、 MYSQLではうまく行きません。どうか御指導をお願い致します。

    • ベストアンサー
    • MySQL
  • サブクエリ内で INNER JOIN は

    グルーピング内で、あるカラムの最大値のレコードで絞り込む方法は、 以下のサイトで知ることができましたが。 http://www.yokablo.com/20120905717.html tb_score +-------+-------+-------+ | c_name | game | c_score | +-------+-------+-------+ | 山田 | 高飛び | 90 | +-------+-------+-------+ | 山田 | 徒競走 | 85 | +-------+-------+-------+ | 山田 | 玉入れ | 90 | +-------+-------+-------+ | 鈴木 | 徒競走 | 85 | +-------+-------+-------+ | 鈴木 | 騎馬戦 | 50 | +-------+-------+-------+ | 室伏 | 綱引き | 100 | +-------+-------+-------+ | 室伏 | 玉入れ | 10 | +-------+-------+-------+ SQL文: SELECT * FROM tb_score INNER JOIN ( SELECT c_name, MAX(c_score) AS MAXSCORE FROM tb_score GROUP BY c_name ) AS TBDUMMY1 USING (c_name) WHERE c_score = MAXSCORE 私の場合、t_score の親テーブル名`t_company`と、 子テーブル`t_items`がありまして、 以下のようなことをやりたかったのですが、エラーとなります。 上記SQL をサブクエリにします。 select * from ( SELECT * FROM tb_score INNER JOIN ( SELECT c_name, MAX( c_score ) AS MAXSCORE FROM tb_score GROUP BY c_name ) AS TBDUMMY1 USING ( c_name ) INNER JOIN t_company ON t_company.c_name = tb_score.c_name WHERE c_score = MAXSCORE ) as T1 , t_items where T1.id_score = t_items.id_score 結果エラーメッセージは、 #1060 - Duplicate column name 'c_name' でした。 エラー箇所が、 GROUP BY c_name か、 USING ( c_name ) か、 INNER JOIN t_company ON t_company.c_name = tb_score.c_name なのか、分かりません。 SQL の規則としてやってはいけないことをやっていると想像してますが、 ご指摘・ご指導いただけると大変に助かります。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • 1対多結合で多を絞り込み条件とするSQLについて

    1対多で結合する場合に、多が絞り込み条件となった場合のSQLについての質問です。 たとえばカスタムテーブルを使ったSELECT文などで、このような絞り込み条件が必要になると思います。 まずカスタムテーブルの具体例として、たとえばユーザーテーブルがあったとします。 [user_table] id=INT //オートインクリメント user_id=VARCHAR //adminなどのユーザーID文字列 user_pass=VARCHAR //パスワードを保存※ハッシュ化した値 user_name=VARCHAR //山田太郎などのユーザー名 user_mail=VARCHAR //ユーザーのメールアドレス user_description=TEXT //ユーザーの自己紹介文 user_created=DATETIME //ユーザーの登録日 とりあえず、上記のようなデータをユーザーの基本データだとします。 このユーザーテーブルから、たとえば名前を元に検索するのは単純です。 たとえばこのような感じでしょうか。 SELECT * FROM user_table WHERE user_name = '山田太郎' このテーブル構造を変更することなくカスタムデータを追加したい(しかも柔軟に)という要望を実現するために、ユーザーカスタムテーブルを作ったとします。 [user_custom_table] id=INT //オートインクリメント relational_id=INT //user_table.idへの参照 custom_name=VARCHAR //カスタムフィールド名 custom_value=VARCHAR //カスタムフィールドの値 custom_name、custom_valueには、たとえばそれぞれ以下のような値が入るとします。 custom_name、custom_value Birthday 、1998/1/1 CompanyName 、○○株式会社 CompanyTel、000-0000-0000 CompanyAddress、東京都千代田区○○-○○ user_custom_table.relational_idはuser_table.idにリレーションしているとすると、INNER JOINして値を取得する方法は判ります。 ※カスタムテーブルに値がない場合という状況は無視できる仕様です。 たとえば、会社住所が東京都で始まるユーザのみを抽出すると、以下のような感じでしょうか。 SELECT user_table.* FROM user_table INNER JOIN user_custom_table ON user_table.id = user_custom_table.relational_id WHERE user_custom_table.custom_name = 'CompanyAddress' AND user_custom_table.custom_value LIKE '東京都%' ただ、この方法だと、誕生日が○月○日以前で、会社名に○○を含んで、会社住所が東京都で始まり…と検索条件が増えていった場合にINNER JOINがどんどん増えていって、いかにも効率が悪いと思えてなりません。 とりあえず適当に書いてみるとして、以下のような感じでしょうか。 SELECT user_table.* FROM user_table INNER JOIN user_custom_table AS custom_1 ON user_table.id = custom_1.relational_id INNER JOIN user_custom_table AS custom_2 ON user_table.id = custom_2.relational_id INNER JOIN user_custom_table AS custom_3 ON user_table.id = custom_3.relational_id WHERE custom_1.custom_name = 'CompanyAddress' AND custom_1.custom_value LIKE '東京都%' AND custom_2.custom_name = 'Birthday' AND custom_2.custom_value < '2001/1/1' AND custom_3.custom_name = 'CompanyName' AND custom_3.custom_value LIKE '%○○%' もっと効率の良い書き方、一般的にはこういう場面ではこんな書き方をするなど、識者の方から教えを請いたくて質問しました。 ※ちなみにDBはMySQLですが、とくにMySQLに限らない方法で答えを頂ける方がありがたいです。

    • ベストアンサー
    • MySQL
  • MysqlのONLY_FULL_GROUP_BY

    MySQLの5.7.9でONLY_FULL_GROUP_BYを有効にしています。 3つのテーブル(a, b, m) を結合して以下のようにgroup byした際、with rollupを付けるとエラーになります。rollup なしでは通ります。これは正しい挙動でしょうか。 select a.aid, a.name, b.bid, sum(m.value) from a inner join b on a.aid = b.aid inner join m on m.bid = b.bid group by a.aid, b.bid a.aid, b.bid はいずれもprimary keyです。 with rollup時のエラーは"SELECT list is not in GROUP BY clause and contains nonaggregated column a.name functionally dependent on columns in GROUP BY clause"という内容ですが、a.nameはテーブルの定義上a.idによって一意に決まる値です。

  • viewでfrom句にサブクエリが書けない

    こんにちは。MYSQLのVIEWの代替についてお教え下さい。 下記でinner joinについて教えて頂きました。 http://okwave.jp/qa/q7296711.html 環境はWin 7 MYQL5です。 t1テーブルのデータ ID,在庫 001,22 t2テーブルのデータ ID,出庫 001,17 001,3 SELECT A.z AS `在庫`,B.* FROM (SELECT SUM(stock) AS z FROM t1 WHERE id='001' GROUP BY id) A INNER JOIN t2 B ON A.id=B.id というコードで、それぞれのテーブルをグループ化してグループ化したもの同士をJOINしました。 このコードを元にVIEWを作り、そのVIEWを対象にクエリを作ろうと考えていました。 しかしながら、MYSQLのVIEWではFROM句でサブクエリは使えませんでした。 http://www.klab.jp/media/mysql/index4.html 上記のコードを書きなおして、なんとしてもVIEWで利用したいのですが、FROM句でサブクエリを使わずにVIEWを作成する方法がわかりません。 どのようにリライトすればよいか、ご助言お願い致します。

    • ベストアンサー
    • MySQL
  • テーブルを結合

    テーブルの結合に関して質問します。 ネットなどでinner joinを使った複数のテーブル結合が参考として 書いてあったのですが(3つまで), 4つテーブルを結合する事は 出来るのでしょうか? A,B,CテーブルにはID,NAMEがあります。 DテーブルにはA,B,CテーブルのIDがあります。 参考サイトを見て3つのテーブルを結合するSQLが以下になります。 SELECT a.name, b.name, c.name FROM a INNER JOIN (b INNER JOIN c ON b.id = c.id) ON a.id = c.id よろしければアドバイスお願いします。

  • inner joinをすると数がおかしくなります

    SQLのinner joinについてお教え下さい。環境はWin 7 MYQL5です。 t1テーブルのデータ ID,在庫 001,22 t2テーブルのデータ ID,出庫 001,17 001,3 SELECT Sum(t1.stock) AS `在庫` FROM t1 where id = '001' 上記SQLの結果は22と表示されます。 SELECT Sum(t1.stock) AS `在庫` FROM t1 INNER JOIN t2 on t1.id = t2.id where id = '001' とやると、結果が44になってしまいます。 なぜそんな結果になってしまうのでしょうか? 結果はt1.stockは在庫22なので、22と表示するようにしたいです。 よろしくお願いいたします。

    • ベストアンサー
    • MySQL