此查询是否使用正确的Oracle语法?
select * from ( ( ( dual a) ) ) where a.dummy = 'X';
它适用于11g和12c,但它是真正有效的语法吗?或者这只是一个编译器“错误”,将来可能会修复,导致代码失败?
我怀疑这是正确的语法,原因如下:
我担心这一点,因为有类似的情况,无效语法在一个版本中起作用,然后在下一个版本中失败。例如: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。
原始查询的样式不好,但除非出现真正的问题,否则不值得更改我们的生产查询。
查询无效吗?或者是否存在某种合法的语法原因,或者语法图中是否存在一些我遗漏的路径?
答案 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;
括号允许您对表b
和c
进行内部联接,然后将其连接到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 JOIN
或RIGHT 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