• 締切済み

正規化して1対多のデータの管理や構造と取り扱い

初めて質問させていただきます。 タイトルはなんとつけたらよいか分からなかったので的外れだったらすみません。 PHP5とMySQL5でプログラムの練習を始めました。 しかしどうしても躓いて分からないところがあり、質問させていただきました。 従業員のデータの入ったテーブル、職種のテーブル、従業員と職種を結ぶテーブルがあるとします。 例えば以下のようなものです。 従業員テーブル +-----------+---------+-----+ | worker_id | name | age | +-----------+---------+-----+ | 1 | hiroshi | 20 | | 2 | seiya | 30 | | 3 | akane | 18 | | 4 | yukari | 18 | +-----------+---------+-----+ 従業員職種テーブル +-----------+--------+ | worker_id | job_id | +-----------+--------+ | 1 | 1 | | 1 | 2 | | 1 | 3 | | 1 | 4 | | 2 | 1 | | 2 | 2 | | 3 | 2 | | 3 | 3 | | 3 | 4 | | 4 | 1 | +-----------+--------+ 職種テーブル +--------+----------+ | job_id | job_name | +--------+----------+ | 1 | hole | | 2 | kitchen | | 3 | delivery | | 4 | cleaning | +--------+----------+ ここで職種cleaningに属する従業員を除いた従業員のデータ一覧を、表示するようなことがしたいと考えています。 このテーブルでいうとhiroshiとakaneはcleaningに属するので除いて、seiyaとyukariのデータが一覧で表示されるという感じです。 select 従業員職種テーブル.worker_id, 従業員テーブル.name, 従業員テーブル.age GROUP_CONCAT(職種テーブル.job_name order by 職種テーブル.job_id) from 従業員職種テーブル left join 従業員テーブル on 従業員職種テーブル.worker_id=従業員テーブル.worker_id left join ot_dow on 従業員職種テーブル.job_id=職種テーブル.job_id group by 従業員職種テーブル.worker_id order by 従業員職種テーブル.worker_id このようなSQLで従業員の職種まで含めたデータを一覧にすることは出来たのですが、対象を除外するような方法が分からずじまいです。 SQLでできるのではと思っていますが、もしかしてPHPでやらなければいけないとかのことも含め、教えていただければ助かります。 よろしくお願いいたします。

みんなの回答

  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.2

元テーブルのデータに特定の条件をつけるのはwhereで 処理結果からデータに特定の条件をつけるのはhavingで 既述します。 例えば、 (質問文の例) where 従業員職種テーブル.job_id not = 4 とか、 (税額を計算して10000円以上を対象にする) select 売上額 * 税率 as 税額 from table1 having 税額 > 10000 とか。 ※いったん対象にして処理をしてから条件を適用するhavingのほうが処理に時間がかかります。 where でできるのならそちらが望ましいです。 質問のSelect文なら、 select 従業員職種テーブル.worker_id, 従業員テーブル.name, 従業員テーブル.age GROUP_CONCAT(職種テーブル.job_name order by 職種テーブル.job_id) from 従業員職種テーブル left join 従業員テーブル on 従業員職種テーブル.worker_id=従業員テーブル.worker_id left join ot_dow on 従業員職種テーブル.job_id=職種テーブル.job_id where 従業員職種テーブル.job_id not = 4 /* これを追加 */ group by 従業員職種テーブル.worker_id order by 従業員職種テーブル.worker_id とかしてみてください。

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

create table t_worker_job(worker_id int, job_id int,index(worker_id,job_id)); insert into t_worker_job values(1,1),(1,2),(1,3),(1,4),(2,1),(2,2),(3,2),(3,3),(3,4),(4,1); として、job_idが4を含むものは select worker_id from t_worker_job group by worker_id having sum(job_id=4)>0 含まないものは select worker_id from t_worker_job group by worker_id having sum(job_id=4)=0

関連するQ&A