2016-04-22 204 views
1

我试图从一个查询中获取ID和USER名称,但同时我正在查看我的WHERE子句,如果ID存在于其他表中。我得到了错误:SQL单行子查询返回多行?

ORA-01427: single-row subquery returns more than one row 

下面是我查询一下:

SELECT s.ID, s.LASTFIRST 
From USERS s 
Left Outer Join CALENDAR c 
On s.ID = c.USERID 
Where c.SUPERVISOR = '103' 
And TO_CHAR(c.DATEENROLLED,'fmmm/fmdd/yyyy') >= '4/22/2016' 
And TO_CHAR(c.DATELEFT,'fmmm/fmdd/yyyy') <= '4/22/2016' 
And s.ID != (SELECT USER_ID 
      From RESERVATIONS 
      Where EVENT_ID = '56') 

我的where子句返回两个ID的内部查询:158和159因此这两个不应该在我的查询返回,我正在寻找s.ID和s.LASTFIRST。什么可能导致这个错误?的!=

!==

回答

4

使用not in代替用于单个ID和值,not inin是用于多个

And s.ID not in (SELECT USER_ID 
       From RESERVATIONS 
       Where EVENT_ID = '56') 

编辑:not in VS not exists

Not exists是一个完美可行的选择好。实际上,如果子查询结果集中存在null值的可能性,则not existsnot in更好 - 在Oracle中,null的存在将导致not in不会返回任何结果。作为一般规则,我使用not in作为ID,而不是空列,not exists用于其他所有内容。我认为总是使用not exists ...个人偏好可能会更好。

Not exists将写成像这样:

SELECT s.ID, s.LASTFIRST 
From USERS s 
Left Outer Join CALENDAR c 
On s.ID = c.USERID 
Where c.SUPERVISOR = '103' 
And TO_CHAR(c.DATEENROLLED,'fmmm/fmdd/yyyy') >= '4/22/2016' 
And TO_CHAR(c.DATELEFT,'fmmm/fmdd/yyyy') <= '4/22/2016' 
And not exists (SELECT USER_ID 
       From RESERVATIONS r 
       Where r.USER_ID = S.ID 
       And EVENT_ID = '56') 

性能

在Oracle中有使用not innot existsleft join之间没有性能差异。

来源https://explainextended.com/2009/09/17/not-in-vs-not-exists-vs-left-join-is-null-oracle/

Oracle's optimizer is able to see that NOT EXISTS, NOT IN and LEFT JOIN/IS NULL are semantically equivalent as long as the list values are declared as NOT NULL.

It uses same execution plan for all three methods, and they yield same results in same time.

+0

谢谢@Aron D.我试图用NOT EXISTS,但没有奏效。不在工作正常。 –

+0

'不在'是缓慢的。有更快的方法来完成同样的事情。 –

+1

@ user3023588最新回答'not exist' –

2

这是一个格式化的评论认为是不相关的你的问题。

这是慢:

And TO_CHAR(c.DATEENROLLED,'fmmm/fmdd/yyyy') >= '4/22/2016' 

,因为你是在一个函数结果进行过滤。

这在逻辑上是等价和更快:

And c.DATEENROLLED >= to_date('4/22/2016','fmmm/fmdd/yyyy') 

编辑从这里开始

亚伦D'的回答说,使用not in。这里有两个更快的方式做同样的事情:

left join reservations r on s.id = user_id 
and r.event_id = '56' 
etc 
where r.user_id is null 

where s.id in 
(
select user_id 
from reservations 
minus 
select user_id 
from reservations 
where event_id = 56 
)  
+0

你的建议是在左连接之后移动event_id而不是在子查询中使用它?效率更高还是? –

相关问题