如何使用两个别名设置WITH查询并选择

时间:2016-10-13 03:31:52

标签: sql oracle join common-table-expression

在SQL的开头使用WITH构造,以执行几个子查询,这些子查询随后可用于Oracle中查询的正文(后续)部分中的多个位置。

你可以在你的例子中加入或匹配t2和t1,即翻译成我的代码,

WITH t1 as (select * from AA where FIRSTNAME like 'Kermit%'),
     t2 as (select * from BB B join t1 on t1.ID = B.ID)

我想我很清楚t1可以在WITH的第二段内引用。

两者是否在括号内选择了几乎可以引用不同表的完整查询,在需要条件的地方使用什么?

我不清楚是否可以使用JOIN在这种情况下匹配来自AA和BB的记录,或者在第二个WITH子句中可能使用不同的连接方法。我看到的一些例子在选择“下方”两个WITH子句的主体中有一个WHERE A = B。

我在这些WITH声明之后得到的错误是t2中的标识符(字段名称)无法识别,但是来自t1的其余SQL引用就好了。似乎WITH语法运行正常,但无法访问第二个WITH段(t2)的结果。

这是整个非工作查询。

with S as (select * from all_records where RESP_MGR like 'Smith%'),
     CHL as (select * from change_log CL JOIN S on S.SERVER_ID = CL.SERVER_ID)

select * from (
   select 
       SERVER_ID as ServerID,
       'Current Environment' as Event,
       SYSDATE as "Date",
       NEW_VALUE as "Data" 
   from CHL
   where OBJECT_DESCR = 'Production'
) 
where "Data" is not null

Oracle说,

 ORA-00904: "SERVER_ID": invalid identifier
 00904. 00000 -  "%s: invalid identifier"

2 个答案:

答案 0 :(得分:1)

我认为这是一个含糊不清的问题。在

CHL as (select * from change_log CL JOIN S on S.SERVER_ID = CL.SERVER_ID)

SERVER_ID中有两列名为SELECT *S.SERVER_IDCL.SERVER_ID。我猜Oracle在其结果集中为它们设置了S_SERVER_IDCL_SERVER_ID的别名。

解决此问题的简单方法是USING子句

CHL as (select * from change_log CL JOIN S using (SERVER_ID))

答案 1 :(得分:1)

Tom Kyte's explanation

  

ANSI SQL将表引用(相关名称)限定为只有一个级别

换句话说,您的主查询(第一级)将能够引用该列,但由于您的子查询(第二级)深度超过一级,因此无法引用该列,这就是原因你收到了错误。

我不知道你的表的结构,但我认为你并不真的需要子查询,而是可以使用这样的东西(空气代码):

with S as (select * from all_records where RESP_MGR like 'Smith%'),
     CHL as (select * from change_log CL JOIN S on S.SERVER_ID = CL.SERVER_ID)
select 
   SERVER_ID as ServerID,
   'Current Environment' as Event,
   SYSDATE as "Date",
   NEW_VALUE as "Data" 
from CHL
where OBJECT_DESCR = 'Production' and NEW_VALUE is not null
;