2009-03-04 59 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! | 
+------+--------+ 

我想选择组a的动作。我的想法是

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
SELECT actions, user FROM userActions 
    WHERE user = (SELECT user FROM userGroupMap WHERE group = a) 

子查询返航用户和组(两个​​场)时,它应该返回只是用户。

+0

我同意子查询部分因为多列而出错;然而,问题是它返回多行,而你的版本仍然这样做 - 因此在运行时失败。 – 2009-03-04 23:57:19

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或其变体完成的。但是这些查询通常可以用连接而不是子查询重写。 – 2009-03-04 23:55:07

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 2009-03-04 21:04:46

+0

如果放在加入的地方呢?这会更好吗? – 2009-03-04 21:06:24

相关问题