2

まず、信じられないほどあいまいで長い質問を許してください。完全な説明なしでクエリを要約する方法が本当にわかりません。

OK、次のような形式の単一の MySQL テーブルがあります

some_table

  • ユーザーID
  • some_key
  • some_value

ユーザーごとに複数の行があると想像すると、次のようになります。

1   |  skill   |   html
1   |  skill   |   php
1   |  foo     |   bar
2   |  skill   |   html
3   |  skill   |   php
4   |  foo     |   bar

HTML をスキルとして挙げているすべてのユーザーを見つけたい場合は、次のように簡単に実行できます。

SELECT user_id
FROM some_table
WHERE some_key = 'skill' AND some_value='html'
GROUP BY user_id

簡単です。これにより、ユーザー ID の 1 と 2 が得られます。

HTMLまたはPHP をスキルとして挙げているすべてのユーザーを見つけたい場合は、次のようにします。

SELECT user_id
FROM some_table
WHERE (some_key = 'skill' AND some_value='html') OR (some_key = 'skill' AND some_value='php')
GROUP BY user_id

これにより、ID の 1、2、および 3 を使用できます。

今、私が苦労しているのは、同じテーブルをクエリする方法ですが、今回は「HTMLPHP の両方をスキルとしてリストしたすべてのユーザーを教えてください」、つまりユーザー ID 1 だけを教えてください。

アドバイス、ガイダンス、またはドキュメントへのリンクは大歓迎です。

ありがとう。

4

3 に答える 3

2

1 つの方法を次に示します。

SELECT user_id
FROM some_table
WHERE user_id IN (SELECT user_id FROM some_table where (some_key = 'skill' AND some_value='html'))
AND user_id IN (SELECT user_id FROM some_table where (some_key = 'skill' AND some_value='php'))
于 2012-04-17T15:33:01.943 に答える
1

これがmysqlで有効かどうかはわかりませんが、そうする必要があります(他のdbエンジンでも機能します):

 SELECT php.user_id 
 FROM some_table php, some_table html 
 WHERE php.user_id = html.user_id 
   AND php.some_key = 'skill' 
   AND html.some_key = 'skill' 
   AND php.some_value = 'php' 
   AND html.some_value = 'html';

または、HAVING ステートメントを使用して、次のようにします。

SELECT user_id, count(*) 
FROM some_table 
WHERE some_key = 'skill' 
  AND some_value in ('php','html') 
GROUP BY user_id 
HAVING count(*) = 2;

3 つ目のオプションは、内部選択を使用することです。Davidのアプローチに対するわずかな代替アプローチ:

SELECT user_id FROM some_table
WHERE 
   some_key = 'skill' AND
   some_value = 'html' AND
   user_id IN (
       SELECT user_id FROM some_table 
       WHERE 
           some_key = 'skill' AND
           some_value = 'php' AND 
           user_id IN (
               SELECT user_id FROM some_table 
               WHERE 
                   some_key = 'skill' AND
                   some_value = 'js' -- AND user_id IN ... for next level, etc.
           )
    );

...アイデアは、内側の選択を「パイプ」できるということです。新しいプロパティごとに、新しい内部選択を最も内側の選択に追加します。

于 2012-04-17T15:31:48.480 に答える
1

ネストされたクエリ(または異なる自己結合)を使用する必要があります

次のテーブルを設定しました。

+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int(11)  | YES  |     | NULL    |       |
| type  | char(10) | YES  |     | NULL    |       |
| value | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+

次の値を挿入しました

+------+-------+-------+
| id   | type  | value |
+------+-------+-------+
|    1 | skill | html  |
|    1 | skill | php   |
|    2 | skill | html  |
|    3 | skill | php   |
|    2 | skill | php   |
+------+-------+-------+

このクエリを実行しました

select id 
from test 
where type = 'skill' 
and value = 'html' 
and id in (
select id 
from test 
where type = 'skill' 
and value = 'php');

そして得た

+------+
| id   |
+------+
|    1 |
|    2 |
+------+

自己結合は次のようになります

select e1.id
from test e1, test e2
where e1.id = e2.id
and e2.type = 'skill'
and e2.value = 'html'
and e1.type = 'skill'
and e1.value = 'php'
;

同じ結果が得られます。

したがって、コードでそれを試すには 2 つの方法があります。

于 2012-04-17T16:05:14.137 に答える