在MySQL中使用子查询进行选择(使用ANY和in进行子查询)

在MySQL中使用子查询进行选择(使用ANY和in进行子查询),mysql,mysql-error-1242,Mysql,Mysql Error 1242,谢谢你的回答 了解更多信息 这很难解释,所以让我们开始吧 userActions userGroupMap +------+--------+ +------+-------+ | user | action | | user | group | +------+--------+ +------+-------+ | x | acted! | | x | a | | y | acted! | | y | a

谢谢你的回答

了解更多信息


这很难解释,所以让我们开始吧

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! |
+------+--------+
我想选择a组的操作。我的想法是

SELECT actions, user FROM userActions
    WHERE user = (SELECT user, group FROM userGroupMap WHERE group = a)
但显然,这个子查询返回不止一行。我应该使用连接吗

Subquery returns more than 1 row
子查询返回的是用户和组(两个字段),而它应该只返回用户

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)

(修订:如其他人所述,只应返回用户列。)

您不能执行以下操作吗:

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

实际上,此查询将为您提供所需的:

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

使用联接而不是子查询:

SELECT
    userActions.action,
    userActions.user
FROM
    userActions
CROSS JOIN userGroupMap ON 
    userGroupMap.user = userActions.user AND
    userGroupMap.group = 'a'
一种方法是:

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';

在大型表上,这将大大增加临时表的大小,然后再使用group将其缩减。它的效率比连接一个子集的数据要低。如果将statment放在连接的何处呢?这样会更好吗?不需要交叉连接;使用内部连接(或者只是普通连接)。在MySQL中,交叉连接在语法上等同于内部连接(它们可以相互替换)。在标准SQL中,它们不是等价的。内部联接与ON子句一起使用,否则使用交叉联接。谢谢!有了你的回答,我的结果完美无瑕。我也很感激关于大桌子的说明(这就是为什么我接受了你的答案)。你能详细解释一下为什么把group放在括号中-“[group]”吗?没有明显的理由需要子查询;带有筛选WHERE子句的直接内部联接也应该起作用。@Blaine:我将[group]放在括号中,因为它是一个关键字,如果没有明确说明用作列/表名的关键字,某些DBMS会崩溃。同样的原因,我把[表格]放在括号里@乔纳森·莱夫勒:你说得对,我想我只是被这个问题分散了注意力,它使用了子查询。再次感谢你,这是一个非常有用的答案!对这在这种情况下效果最好。但也存在“如何处理返回多行的子查询”的问题,这是通过IN or=ANY或其变体完成的。但是这些查询通常可以用连接而不是子查询重写;然而,问题是它返回多行,而您的版本仍然返回多行,因此在运行时失败。
SELECT actions,
       userActions.user
FROM   userActions
       INNER JOIN userGroupMap
       ON     userActions.user = userGroupMap.user
WHERE  [group] = 'a';