Выбор с помощью подзапросов в MySQL (подзапросы с ЛЮБОЙ и IN) - PullRequest
2 голосов
/ 04 марта 2009

Спасибо за отличные ответы!

Для получения дополнительной информации


Это трудно объяснить, поэтому давайте установим сцену ...

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

Ответы [ 6 ]

3 голосов
/ 05 марта 2009

Один из подходов такой:

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';
1 голос
/ 04 марта 2009

Собственно, этот запрос даст вам то, что вам нужно:

SELECT actions, user 
FROM userActions 
WHERE user IN 
    (SELECT user FROM userGroupMap WHERE group = 'a')
1 голос
/ 04 марта 2009

Не могли бы вы просто сделать что-то вроде:

SELECT 
  a.actions, 
  a.user 
FROM 
  userActions a 
  INNER JOIN userGroupMap g 
    ON a.user = g.user
WHERE
  g.group = 'a'
1 голос
/ 04 марта 2009
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)

(Изменено: должен быть возвращен только пользовательский столбец, как отмечено другими.)

0 голосов
/ 05 марта 2009

Лучше использовать объединение, чем подзапрос:

SELECT
    userActions.action,
    userActions.user
FROM
    userActions
CROSS JOIN userGroupMap ON 
    userGroupMap.user = userActions.user AND
    userGroupMap.group = 'a'
0 голосов
/ 04 марта 2009
SELECT actions, user FROM userActions
    WHERE user = (SELECT user FROM userGroupMap WHERE group = a)

Подзапрос возвращал пользователя и группу (два поля), когда он должен был возвращать только пользователя.

...