将子查询转换为连接

时间:2012-01-11 00:25:28

标签: mysql sql join subquery

是否可以将以下子查询转换为JOIN,最好不使用派生表?

SELECT * FROM users u
LEFT JOIN user_groups ug ON u.usergroupid=ug.groupid
WHERE
u.userstatus=1 AND
ug.groupstatus=1 AND
ug.grouprank>=(SELECT grouprank FROM user_groups WHERE groupkey='users')

user_groups表如下所示:

+-------------+---------------------+------+-----+---------+----------------+
| Field       | Type                | Null | Key | Default | Extra          |
+-------------+---------------------+------+-----+---------+----------------+
| groupid     | tinyint(3) unsigned | NO   | PRI | NULL    | auto_increment |
| groupkey    | varchar(8)          | NO   |     | NULL    |                |
| grouprank   | smallint(6)         | NO   |     | NULL    |                |
| groupstatus | tinyint(1) unsigned | NO   |     | NULL    |                |
+-------------+---------------------+------+-----+---------+----------------+

用户表格如下:

+--------------+---------------------+------+-----+---------+----------------+
| Field        | Type                | Null | Key | Default | Extra          |
+--------------+---------------------+------+-----+---------+----------------+
| userid       | int(10) unsigned    | NO   | PRI | NULL    | auto_increment |
| username     | varchar(32)         | NO   |     | NULL    |                |
| userpassword | varchar(32)         | NO   |     | NULL    |                |
| usergroupid  | tinyint(3) unsigned | NO   |     | NULL    |                |
| userstatus   | tinyint(1) unsigned | NO   |     | NULL    |                |
+--------------+---------------------+------+-----+---------+----------------+

2 个答案:

答案 0 :(得分:2)

假设只有一个user_groups记录有groupkey = 'users'(因为否则您的查询无效),您的查询就等同于:

SELECT u.*,
       ug1.*
  FROM users u
  LEFT
  JOIN user_groups ug1
    ON u.usergroupid = ug1.groupid
  LEFT
  JOIN user_groups ug2
    ON ug2.groupkey = 'users' -- not a real join condition
 WHERE u.userstatus = 1
   AND ug1.groupstatus = 1
   AND ug1.grouprank >= ug2.grouprank
;

但请注意,LEFT JOIN实际上最终以INNER JOIN的形式运行,因为您的WHERE子句取决于连接成功。所以你可能真的想要这样的东西:

SELECT u.*,
       ug1.*
  FROM users u
  LEFT
  JOIN user_groups ug1
    ON u.usergroupid = ug1.groupid
   AND ug1.groupstatus = 1
  LEFT
  JOIN user_groups ug2
    ON ug2.groupkey = 'users'
   AND ug1.grouprank >= ug2.grouprank
 WHERE u.userstatus = 1
;

答案 1 :(得分:1)

我认为这就是你要找的 - 给它一个测试。

SELECT * FROM users u
LEFT JOIN user_groups ug ON u.usergroupid=ug.groupid
JOIN user_groups ug2 ON ug.grouprank >= ug2.grouprank AND ug2.groupkey = 'users'
WHERE
u.userstatus=1 AND
ug.groupstatus=1