我有以下sql,它运行正常(Oracle数据库12c企业版版本12.1.0.2.0-64位生产)。
with n as (
select ntile(cnt) over ( partition by cnt order by Id ) NT, Id
from t
)
select n.NT, high.Id
from (select distinct NT from n) n
outer apply (
select *
from n x where x.NT = n.NT and rownum = 1 order by Id
) low
outer apply (
select *
from (select * from n x where x.NT = n.NT order by Id desc) d where rownum = 1
) high
现在我将其更改为以下内容,
with n as (
select ntile(cnt) over ( partition by cnt order by Id ) NT, Id
from t
)
select n.NT, phigh.Id -- Error - phigh.Id
from (select distinct NT from n) n
outer apply (
select *
from n x where x.NT = n.NT and rownum = 1 order by Id
) low
outer apply (
select *
from (select * from n x where x.NT = n.NT order by Id desc) d where rownum = 1
) high
outer apply (
select *
from (select * from n x where x.NT = n.NT-1 order by Id desc) d where rownum = 1
) phigh
现在它在phigh.Id
上出现以下错误:
ORA-00918:列定义不明确
- 00000-“列定义不明确”
如果我将phigh.Id
更改为phigh.*
,则第二个查询有效吗?将phigh.Id
更改为high.Id
也可以。
试图使用与CTE不同的别名。仍然出现相同的错误
with n as (
select ntile(cnt) over ( partition by cnt order by Id ) NT, Id
from t
)
select n.NT, phigh.Id -- Error - phigh.Id
from (select distinct NT from n) nt
outer apply (
select *
from n x where x.NT = nt.NT and rownum = 1 order by Id
) low
outer apply (
select *
from (select * from n x where x.NT = nt.NT order by Id desc) d where rownum = 1
) high
outer apply (
select *
from (select * from n x where x.NT = nt.NT-1 order by Id desc) d where rownum = 1
) phigh
以下可测试的查询出错。
with t as (
select 10 as cnt, 1 as Id from dual
),
x as (
select ntile(cnt) over ( partition by cnt order by Id ) NT, Id
from t
)
select n.NT,
high.Id a,
phigh.Id
from (select distinct NT from x) n
outer apply (select * from x where x.NT = n.NT and rownum = 1 order by Id) low
outer apply (select * from (select * from x where x.NT = n.NT order by Id desc) d where rownum = 1) high
outer apply (select * from (select * from x where x.NT = n.NT - 1 order by Id desc) d where rownum = 1) phigh
以下代码有效。
with t as (
select 10 as cnt, 1 as Id from dual
),
x as (
select ntile(cnt) over ( partition by cnt order by Id ) NT, Id
from t
)
select n.NT,
--high.Id a,
phigh.Id
from (select distinct NT from x) n
outer apply (select * from x where x.NT = n.NT and rownum = 1 order by Id) low
--outer apply (select * from (select * from x where x.NT = n.NT order by Id desc) d where rownum = 1) high
outer apply (select * from (select * from x where x.NT = n.NT - 1 order by Id desc) d where rownum = 1) phigh
答案 0 :(得分:0)
对于主查询和cte,您应该使用不同的别名,现在它们是相同的n
:
with n_cte as (
select /*+ materialize*/ ntile(cnt) over ( partition by cnt order by Id ) NT, Id
from tab
)
select n.NT, phigh.Id
from (select distinct NT from n_cte) n
outer apply (
select *
from n_cte where n.NT = n_cte.NT and rownum = 1 order by Id
) low
outer apply (
select *
from (select * from n_cte where n_cte.NT = n.NT order by Id desc) d where rownum = 1
) high
outer apply (
select *
from (select * from n_cte where n_cte.NT = n.NT-1 order by Id desc) d where rownum = 1
) phigh
另一个选择是在cte部件内添加SELECT /*+ materialize*/ ...
提示。
答案 1 :(得分:0)
我发现重命名high
中共享的列名,并且'phigh`起作用。
with t as (
select 10 as cnt, 1 as Id from dual
),
x as (
select ntile(cnt) over ( partition by cnt order by Id ) NT, Id
from t
)
select n.NT,
high.Id a,
phigh.Id
from (select distinct NT from x) n
outer apply (select * from x where x.NT = n.NT and rownum = 1 order by Id) low
outer apply (select Id z from (select * from x where x.NT = n.NT order by Id desc) d where rownum = 1) high
outer apply (select * from (select * from x where x.NT = n.NT - 1 order by Id desc) d where rownum = 1) phigh
但这对我(问题所有者)来说真的不是解决方案。该代码将动态生成,并且会有很多列。
当多个子查询返回具有相同名称的列并且这些列在select子句中时,Oracle似乎有问题。
将outer apply (select * from x where x.NT = n.NT and rownum = 1 order by Id) low
更改为outer apply (select * from x where x.NT = 1 and rownum = 1 order by Id) low
也将消除该错误。