将子查询(不在)重写为加入
Posted
技术标签:
【中文标题】将子查询(不在)重写为加入【英文标题】:Rewrite Subquery(not in) as Join 【发布时间】:2010-09-29 14:12:51 【问题描述】:大家好,是否可以重写查询:
select userid from User where userid not in(select userid from UserRole where roleid in(8));
加入?
问题是一个用户可能有多个角色 先感谢您。
mysql> desc 用户; +--------------------+--------+------+- ----+---------+----------------+ |领域 |类型 |空 |钥匙 |默认 |额外 | +--------------------+--------+------+- ----+---------+----------------+ |用户名 |整数(11) |否 |优先级 |空 |自动增量 | |用户名 | varchar(50) |是 | |空 | |...和其他用户相关的列
mysql> desc 用户角色; +--------+---------+------+-----+---------+------- + |领域 |类型 |空 |钥匙 |默认 |额外 | +--------+---------+------+-----+---------+------- + |用户名 |整数(11) |否 |优先级 | 0 | | |角色标识 |整数(11) |否 |优先级 | 0 | | +--------+---------+------+-----+---------+------- +【问题讨论】:
【参考方案1】:也许这会起作用?
select userid from User
left outer join
(select userid, roleid from UserRole where roleid in(8)) v
on User.userid = v.userid
where roleid is null;
【讨论】:
OP想将子查询重写为join,但是这个查询还有子查询。 @ShivanRaptor: (a) OP 没有指定没有子查询只是“我可以重写为连接吗”; (b) OP 已经接受了我的回答,大概对此很满意; (c) 这一切都发生在将近 4 年前! ;-)【参考方案2】:我认为这应该让您拥有除 8 之外的所有角色
select userid from User
where not exists
(select UserId from UserRole
where UserRole.userid = User.userid and roleid not in(8) )
【讨论】:
【参考方案3】:如果您想提高可读性,可以使用 EXCEPT 子句。
即
select userId from user
except
select userId from UserRole where roleId <> 8
不确定 MySQL 是否支持“Except”。
【讨论】:
注意:MySQL 不支持EXCEPT
【参考方案4】:
我没有对此进行测试,但我认为它有效。
select userID from user
left join UserRole
on user.userID = UserRole.userID
and UserRole.roleID = 8
where UserRole.roleID IS NULL
【讨论】:
注:可以使用表别名以上是关于将子查询(不在)重写为加入的主要内容,如果未能解决你的问题,请参考以下文章