我们说我们有这个愚蠢的问题:
Select * From Emp Where Id In (Select Id From Emp)
通过添加IN
子句,让我们在Order By
条件内进行一些小修改。
Select * From Mail Where Id In (Select Id From Mail Order By Id)
然后我们收到以下错误:
ORA-00907:缺少右括号
Oracle假定IN条件将在声明From表后结束。因此,等待右括号,但我们给出了一个Order By。 为什么我们不能在IN条件下添加Order By?
仅供参考:我不会要求提供相同的查询。毕竟这是一个例子。我无法理解为什么会出现这种错误。
答案 0 :(得分:3)
考虑条件x in (select something from somewhere)
。如果x
等于查询返回的任何something
,则返回true - 无论它是第一个,第二个,最后一个还是中间的任何内容。返回something
s的顺序无关紧要。在查询中添加order by
子句通常会带来很大的性能损失,所以我猜测这个限制是为了防止添加一个对查询的正确性没有影响的子句。一方面,另一方面可能相当昂贵。
答案 1 :(得分:1)
对 IN 子句中的值进行排序是没有意义的。以这种方式思考:
IN (a, b, c)
与
相同IN (c, b, a)
与之相同
IN (b, c, a)
Oracle内部应用 OR 条件,因此它等同于:
WHERE id = a OR id = b OR id = c
订购条件会有意义吗?
订购需要自费。因此,当不需要排序时,就是不要这样做。在这种情况下,Oracle应用了相同的规则。
当涉及到查询的性能时,优化器需要选择最佳的执行计划,即以最低的成本来实现所需的输出。在这种情况下,ORDER BY是无用的,并且 Oracle在防止使用它方面做得很好。
Type of Condition Operation ----------------- ---------- IN Equal-to-any-member-of test. Equivalent to =ANY.
因此,当您需要为值列表中的成员资格测试 ANY 值时,不需要有序列表,只需进行随机匹配即可。
答案 2 :(得分:1)
如果你看一下Oracle SQL参考(语法图),你会发现一个原因。 ORDER BY是" select"的一部分。声明,而IN
子句使用情人级别"子查询"声明。您的问题与Oracle SQL语法的本质有关。
PS:可能会有更多问题,例如多个UNION
,MINUS
on"子查询"然后你也可以只使用一个ORDER BY
子句,因为这只适用于UNION
操作的结果。
这也会失败:
select * from dual order by 1
union all
select * from dual order by 1;