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