FROM子句中的嵌套括号是否有效Oracle SQL语法?

时间:2016-01-12 22:26:54

标签: oracle oracle11g oracle12c

此查询是否使用正确的Oracle语法?

select * from ( ( ( dual a) ) ) where a.dummy = 'X';

它适用于11g和12c,但它是真正有效的语法吗?或者这只是一个编译器“错误”,将来可能会修复,导致代码失败?

我怀疑这是正确的语法,原因如下:

  1. 除了添加额外的括号之外,它似乎没有做任何其他事情。像((1 + 2)* 3)这样的表达式显然可以从嵌套括号中受益,但是我看不出它们如何帮助FROM子句。当我查看上面的查询时,别名“a”看起来超出了范围。
  2. 我在SQL Language Reference syntax diagrams中找不到此语法的有效路径。另一方面,很容易看到expressionsconditions如何允许使用嵌套括号, 和subqueries。表达式,条件和子查询是递归的,可以包含括号,但是join子句不是递归的。
  3. 我担心这一点,因为有类似的情况,无效语法在一个版本中起作用,然后在下一个版本中失败。例如:select (select count(*) from (select * from scott.emp where ename = dual.dummy)) from dual;。该查询在10.2.0.1.0中有效,但在更高版本中停止工作,因为table references are scoped to only one level deep

    原始查询的样式不好,但除非出现真正的问题,否则不值得更改我们的生产查询。

    查询无效吗?或者是否存在某种合法的语法原因,或者语法图中是否存在一些我遗漏的路径?

3 个答案:

答案 0 :(得分:5)

FROM join子句中使用括号是合法的语法,而括号 do 会产生效果。

考虑这个问题:

WITH table_a AS ( SELECT rownum id FROM DUAL CONNECT BY LEVEL <= 30),
     table_b as ( SELECT rownum id FROM DUAL CONNECT BY LEVEL <= 20),
     table_c AS ( SELECT rownum id FROM DUAL CONNECT BY LEVEL <= 10)
SELECT a.id, b.id, c.id
FROM   table_a a left join ( table_b b inner join table_c c ON c.id = b.id ) ON b.id = a.id 
ORDER BY 1,2,3;

括号允许您对表bc进行内部联接,然后将其连接到a

没有括号,试图将其表示为左连接是不可能的。您要么不会从表a获取11-30行,要么表c的第11-20行将是null s(取决于您尝试的方式)。< / p>

请注意,上述查询等同于:

WITH table_a AS ( SELECT rownum id FROM DUAL CONNECT BY LEVEL <= 30),
     table_b as ( SELECT rownum id FROM DUAL CONNECT BY LEVEL <= 20),
     table_c AS ( SELECT rownum id FROM DUAL CONNECT BY LEVEL <= 10)
SELECT a.id, b.id, c.id
FROM   table_b b inner join table_c c on c.id = b.id right join table_a a on a.id = b.id 
ORDER BY 1,2,3;

,不需要括号。因此,如果您真的想避免在FROM子句中使用括号,通常可以这样做。就个人而言,我更喜欢使用括号而不是LEFT JOIN的{​​{1}}方法。

答案 1 :(得分:3)

根据我对syntax diagram for a SELECT statement的解读,不允许在SELECT语句中的括号内引用括号。至于Oracle是否可以修复&#34;事情会使这个无效,我无法知道,但我认为这不太可能。 YMMV。

祝你好运。

修改

为了好玩,我想我已经放下了对语法图的阅读:

正如其他人所指出的那样,join_clause周围允许使用 括号,但dual a不是join_clause。相反,它是query_table_expression,是table_reference的一部分。 dual a不能join_clause - 必须遵循inner_join_clause(例如INNER JOIN)或outer_join_clause(例如{{1} }},LEFT OUTER JOINRIGHT OUTER JOIN),它不是。根据语法图,FULL OUTER JOIN 不允许使用括号,除非<{em} query_table_expression前面有query_table_expression,并且在OP查询{{1}中}之前没有ONLY。因此,我得出结论,根据Oracle语法图dual a在语法上不正确;但是,数据库似乎不同意。 : - )

答案 2 :(得分:1)

join_clause 子查询的附加内容可能是nested

所以这是完美有效的语法

var

这提供了质疑查询的synax有效性的线索。

 (((select * from dual)));

select开始,我们转到query_block

select * from (((dual)));

select --> subquery --> query_block扩展为

query_block

SELECT * FROM table_reference 我们下降到(嵌套)table_reference,可以进一步嵌套。

subquery

因此,请继续展开table_reference --> query_table_expression --> ( subquery )以获得必要的嵌套,最后选择subquery作为query_table_expression的扩展

但正如MT0和其他人所指出的那样,遗憾的是,这并未导致e3xpected结果。最大合法查询是

TABLE