以下のときの、SQLの書き方がわからないので教えてください


3つのテーブルがあります

・社員テーブル (T_USER)
1,鈴木
2,佐藤
3,斉藤
4,佐々木
5,山本


・スキルテーブル (T_SKILL)
1,英語
2,中国語
3,韓国語
4,プログラミング
5,設計
6,インフラ
7,ネットワーク
8,マーケティング
9,SEO


・社員スキルテーブル (T_USER_SKILL)
社員スキルID, 社員ID, スキルID
1,1,1
2,1,2
3,1,4
4,2,1
5,2,6
6,3,4
6,3,5
6,3,6





このようなとき、英語もしくは中国語ができる人を探すのは以下のようなSQLで出来ることがわかりました
select B.name from (select user_id from T_USER_SKILL where skill_id in (1,2)) A left join T_USER B on A.user_id = B.user_id;

英語と中国語、両方出来る人を探すにはどのように書いたら良いのでしょうか。

よろしくお願いします。

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2013/03/25 17:46:16
  • 終了:2013/03/27 17:20:03

回答(2件)

id:taknt No.1

きゃづみぃ回答回数13537ベストアンサー獲得回数11982013/03/25 18:20:12

ポイント100pt

select B.name from (
select distinct A1.user_id1 user_id from
(select A1.user_id user_id1,A1.skill_id from T_USER_SKILL A1 Where A1.skill_id = 1) A1 inner join
(select A2.user_id user_id4,A2.skill_id from T_USER_SKILL A2 Where A2.skill_id = 2) A4
on A1.user_id1 = A4.user_id4
) A left join T_USER B on A.user_id = B.user_id

こんな感じでいいでしょう。

id:spacewarp

参考になりました。ありがとうございました。

2013/03/27 17:19:24
id:windofjuly No.2

うぃんど回答回数2625ベストアンサー獲得回数11492013/03/25 18:29:09

ポイント100pt

例を2つほど

該当するスキルを単純に数える方法

SELECT B.name
FROM (
    SELECT user_id
    FROM T_USER_SKILL
    WHERE skill_id in (1, 2)
    GROUP BY user_id
    HAVING count(*) = 2
) A
LEFT JOIN T_USER B ON A.user_id = B.user_id
;

該当するスキルをAND条件で繋ぐ方法

SELECT B.name
FROM (
    SELECT A1.user_id
    FROM T_USER_SKILL A1
    LEFT JOIN  T_USER_SKILL A2 ON A2.user_id = A1.user_id
    WHERE A1.skill_id = 1 AND A2.skill_id = 2
) A
LEFT JOIN T_USER B ON A.user_id = B.user_id
;
id:spacewarp

参考になりました。ありがとうございました。

2013/03/27 17:19:41
  • id:taknt
    なるほど countは使えないということか。
  • id:taknt
    勉強になった。
  • id:taknt
    ちなみに 回答した本人は理解してないようなので 指摘しますが

    No2の回答の最初のSQLでは、社員が 3つ以上のスキルを持っている場合、
    つまり 英語と中国語とそれ以外のスキルを 持っている人は 抽出されません。

    あと No2の回答の二番目のSQLは 同じ人が 複数抽出されてしまいます。
  • id:windofjuly
    うぃんど 2013/03/25 19:02:39
    >きゃづみぃ 2013/03/25 18:52:15
    >最初のSQLでは、社員が 3つ以上のスキルを持っている場合、
    >つまり 英語と中国語とそれ以外のスキルを 持っている人は 抽出されません。

    WHERE skill_id in (1, 2) にて英語と中国語だけに条件を絞ってあるので、
    他のスキルの有無は関係なく英語と中国語を両方話せる人を抽出できます。

    >きゃづみぃ 2013/03/25 18:52:15
    >No2の回答の二番目のSQLは 同じ人が 複数抽出されてしまいます

    これはそのとおりです。
    WHEREの次に GROUP BY A1.user_id を入れれば一人一レコードにできますので、必要であれば追加してください。
  • id:taknt
    というか 一番目と二番目の結果が 違うんだけど。
  • id:windofjuly
    うぃんど 2013/03/25 19:19:01
    >きゃづみぃ 2013/03/25 19:04:22
    >一番目と二番目の結果が 違う

    サンプルデータと実行したSQLと結果をどうぞ。
  • id:taknt
    そんな簡単なことも わからんのね。
    ま、私が 回答したものを使ってもらえればいいので それは それとして質問者さんには
    参考にしてもらえればいいと思います。

  • id:windofjuly
    うぃんど 2013/03/25 19:31:34
    きゃづみぃ(id:taknt) さんの指摘に対し、
    私は誠実に WHERE skill_id in (1, 2) にて制限してあると回答していますが、
    それに対してのコメントがまったくありませんので、今も誤解したままでおられる可能性が高く、
    回答ならびにコメントした立場として、誠実に対応してください。

    >私が 回答したものを使ってもらえればいいの

    GROUP BY や HAVING などのSQLの基礎を理解していれば簡単に済むものを、
    SELECTを何重にもする必要のない場面であのような応用性のないものを選らんで使ってもらうとすれば残念です。


    誠実な対応を行わないならばガイドラインの注意事項違反です。
    ぜひとも誠実な対応をよろしくどうぞ。

    まずは、サンプルデータと実行したSQLと結果をよろしくどうぞ。
    それと、WHERE skill_id in (1, 2)についての申し開きか謝罪もあわせてよろしく。

    http://q.hatena.ne.jp/help/guideline
    >>
    本サービスに投稿した質問や回答、コメントに対して、反論、指摘や追加情報を求める内容が投稿される場合がありますが、ご自身の責任において誠実に対応を行ってください
    <<
  • id:taknt
    >私は誠実に WHERE skill_id in (1, 2) にて制限してあると回答していますが、

    別に そういうふうに とらえるんなら それでいいですということです。

    ただ二番目のSQLには
    WHERE skill_id in (1, 2)
    は 使ってないですよね?

    ということは
    WHERE skill_id in (1, 2) にて制限してある
    のとは 違うということです。

    ちなみに 実行したSQLと言ってますが、 №2の回答にあるSQLで 何も修正してませんけど。

  • id:taknt
    あと テストデータも 質問にあるようなものに 数件 追加したぐらいですがね。

    どのようなテストをしたらいいのか 想像できないようでしたら コメントしてください。

  • id:taknt
    私が 誠意をもって わからない人に 教えてあげましょう。
  • id:taknt
    あと 私も そんなに 暇じゃないので しばらくコメントがないからといって 怒らないでくださいね。
  • id:windofjuly
    うぃんど 2013/03/25 19:55:38
    >きゃづみぃ 2013/03/25 19:38:24
    >ただ二番目のSQLには
    >WHERE skill_id in (1, 2)
    >は 使ってないですよね?

    何が「ただ」ですか?
    二番目のほうはJOINを用いて横に並べる形になっているので、
    下記のようにな形でフィルタをかけてます。
    WHERE A1.skill_id = 1 AND A2.skill_id = 2

    あなたが指摘したのは一番目のほうです。
    話をはぐらかそうとしないで誠実に対応してください。


    >きゃづみぃ 2013/03/25 19:38:24
    >ちなみに 実行したSQLと言ってますが、 №2の回答にあるSQLで 何も修正してませんけど。

    何も修正していないならデータのほうにミスがあるのでしょうとしか言えませんが、
    どうせあなたは「質問文通りです」と答えるつもりでしょうね。

    仮に質問文通りだとして、では具体的にそれぞれどのような結果になったのですか?
    結果を書くだけでよいのに、なぜ書かないのですか? いいわけを考えてませんか?

    繰り返します。誠実に対応してください。
  • id:windofjuly
    うぃんど 2013/03/25 19:57:36
    こちらがコメント書いている間に入れ違いになった部分がありますが、大筋で変更はありませんとだけ書いておきます。

    誠実な対応を期待します。
  • id:taknt
    一番目のSQLは 英語と中国語が両方出来る人のみでしたが
    二番目のSQLは 英語と中国語の両方のみと、英語と中国語とそれ以外にもできる人も抽出されています。

    このような結果の食い違いから

    私が指摘したことによる返答
    >>最初のSQLでは、社員が 3つ以上のスキルを持っている場合、
    >>つまり 英語と中国語とそれ以外のスキルを 持っている人は 抽出されません。
    >WHERE skill_id in (1, 2) にて英語と中国語だけに条件を絞ってあるので、
    >他のスキルの有無は関係なく英語と中国語を両方話せる人を抽出できます。

    により、ぜんぜん理解されてないということが わかりました。

    もちろん質問者が必要とする回答は、私が既にしていますので
    わざわざ修正していただく必要は ない ということです。

    ただ、質問者の方には、そのような違いがあるということだけは 理解してもらいたかっただけです。
  • id:windofjuly
    うぃんど 2013/03/25 20:36:16
    >きゃづみぃ 2013/03/25 20:23:02
    >一番目のSQLは 英語と中国語が両方出来る人のみでしたが
    >二番目のSQLは 英語と中国語の両方のみと、英語と中国語とそれ以外にもできる人も抽出されています。

    英語と中国語の両方使える人を抽出するという点でどちらも同じですから、
    質問者さんが求めている結果は出してますが、それが何か問題でも?

    出来る限り基本に忠実に簡単な構文にしての2例で、
    それぞれ理解した上で使い分けてもらえば良いだけですが、それが何か問題でも?

    ところで、長々とやってきた結果が「コレだけ」ですか?
    これだけのことをどうして最初の一回に書かなかったのですか?

    次回があれば、もっと誠実にわかりやすいようにコメントするようにしていただきたいです。
  • id:taknt
    SQLの実行結果が 違うことは 非常に大きいことだと思いますけど。

    >英語と中国語の両方使える人を抽出するという点でどちらも同じですから、
    >質問者さんが求めている結果は出してますが、それが何か問題でも?

    一番目のSQLだと ほかのスキルがある人は抽出されません。
    これは 問題じゃないと 言い切るなら 私は何もいいませんが。

  • id:windofjuly
    うぃんど 2013/03/25 21:41:25
    きゃづみぃ 2013/03/25 21:20:35>一番目のSQLだと ほかのスキルがある人は抽出されません。

    WHERE skill_id in (1, 2) で英語あるいは中国語のスキルを持っているデータだけに絞り、
    さらに count(*)=2 で両方もった人に限定するという二段で処理しています。

    このことは、一番最初の私のコメントで下記のように説明したはずです。
    「WHERE skill_id in (1, 2) にて英語と中国語だけに条件を絞ってある」

    GROUP BY と HAVING count(*) = ほげほげ という書き方はSQLの基礎ですから、
    何度も同じことを書かないでください。


    きゃづみぃ 2013/03/25 21:20:35>私は何もいいませんが

    あなたがSQLを理解できないことは重々わかりましたが、
    あなたの書いたコメントに対しての訂正と謝罪は要求させていてだきます。

    訂正ならびに謝罪を行わないのであれば、ガイドラインの注意事項違反として、
    これまでの言動も踏まえて厳正に対処させていただきます。

    訂正ならびに謝罪はこの質問の自動終了日時までは待つこととします。
    ゆっくりと吟味して、言葉を選んで、誠実な対応をなさることを期待します。

    誠意が見られない場合は、即座に対応させていただく所存ですから、よろしくどうぞ。

    なお、
    私の回答をなんとか捻じ曲げようと努力するだけの きゃづみぃ(id:taknt) とのやりとりは無駄なだけなので、
    ここでの、きゃづみぃ(id:taknt) からの問いかけに対しては答えないようにします。

    こちらが求めるのは訂正と謝罪のみです。
  • id:taknt
    間違った回答をしているくせに 謝罪と訂正を要求するとは ひどい話です。

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

トラックバック

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

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

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