2009-03-04 8 views
2

すばらしい答えをありがとう!MySQLでサブクエリを使用して選択する(ANY、INを持つサブクエリ)

詳細情報


これは説明するのは難しいですので、段階を設定...

ができます
userActions   userGroupMap 
+------+--------+ +------+-------+ 
| user | action | | user | group | 
+------+--------+ +------+-------+ 
| x | acted! | | x | a  | 
| y | acted! | | y | a  | 
| y | acted! | | z | b  | 
| z | acted! | +------+-------+ 
| y | acted! | 
| z | acted! | 
| x | acted! | 
| z | acted! | 
+------+--------+ 

グループのアクションを選択したいと思います。私の考えは

SELECT actions, user FROM userActions 
    WHERE user = (SELECT user, group FROM userGroupMap WHERE group = a) 

にした。しかし、明らかにこのサブクエリは複数の行を返します。私はJOINを使うべきですか?

Subquery returns more than 1 row 

答えて

3

一つの方法は以下です:

SELECT actions, 
     user 
FROM userActions 
WHERE user IN 
       (SELECT user 
       FROM userGroupMap 
       WHERE [group] = 'a' 
       ); 

しかし、大きなテーブルで、このクエリが参加し、非効率的とやってする傾向があるほうがよい。また

SELECT actions, 
     userActions.user 
FROM userActions 
     INNER JOIN 
       (SELECT user 
       FROM userGroupMap 
       WHERE [group] = 'a' 
      ) AS tmp 
     ON  userActions.user = tmp.user; 

、ジョナサンが述べたように、あなたはこれ以上、それほど効率的でなくても、これほど効率的であったかもしれません:

SELECT actions, 
     userActions.user 
FROM userActions 
     INNER JOIN userGroupMap 
     ON  userActions.user = userGroupMap.user 
WHERE [group] = 'a'; 
+0

ありがとうございました!あなたの答えで、私は完璧な結果を得ました。私はまた大きなテーブルについての注記に感謝します(それがあなたの答えを受け入れた理由です)。 括弧で囲んだ理由を詳しく説明できますか?「[group]」? – Blaine

+0

サブクエリが必要な理由は何もありません。 WHERE句をフィルタリングするストレートインナージョインも、この作業を行う必要があります。 –

+0

@Blaine:括弧内に[group]を入れます。なぜなら、列/表名として使用されるキーワードが明示的に指定されていなければ、キーワードとDBMSが狂ってしまうからです。同じ理由で私は[表]を括弧で囲みます。 @Jonathan Leffler:そうです、質問に気を取られ、サブクエリを使用しているだけです。 – achinda99

0
SELECT actions, user FROM userActions 
    WHERE user = (SELECT user FROM userGroupMap WHERE group = a) 

それだけユーザを返すされなければならない場合、サブクエリは、ユーザおよびグループ(2つのフィールド)を返すました。

+0

複数の列のためにサブクエリが部分的に間違っていたことに同意します。しかし、問題はそれが複数の行を返すことであり、あなたのバージョンはまだそれを行います - したがって、実行時に失敗します。 –

1
SELECT actions, user FROM userActions 
    WHERE user IN (SELECT user FROM userGroupMap WHERE group = a) 

SELECT actions, user FROM userActions 
    WHERE user = ANY (SELECT user FROM userGroupMap WHERE group = a) 

(改正:。他の人が指摘したようにのみ、ユーザーの列は、返されるべきである)

1

は、あなただけのような何かができませんでした:実は

SELECT 
    a.actions, 
    a.user 
FROM 
    userActions a 
    INNER JOIN userGroupMap g 
    ON a.user = g.user 
WHERE 
    g.group = 'a' 
+0

はい。この状況ではこれが最も効果的です。しかし、「複数の行を返すサブクエリを処理する方法」の問題もあり、INまたはANYまたはその変形で行われます。しかし、これらのクエリはサブクエリの代わりに結合で書き直すことができます。 –

1

を、このクエリが得られますあなたが必要なものをあなた:

SELECT actions, user 
FROM userActions 
WHERE user IN 
    (SELECT user FROM userGroupMap WHERE group = 'a') 
0

むしろサブクエリよりも結合を使用:

SELECT 
    userActions.action, 
    userActions.user 
FROM 
    userActions 
CROSS JOIN userGroupMap ON 
    userGroupMap.user = userActions.user AND 
    userGroupMap.group = 'a' 
+0

大きなテーブルでは、一時テーブルのサイズを大幅に大きくしてから、グループで切り捨てます。データのサブセットに結合するより効率的ではありません。 – achinda99

+0

statmentがどこに参加するのか?それは良いでしょうか? –

+0

CROSS JOINは不要です。 INNER JOIN(または単純なJOIN)を使用します。 –

関連する問題