约束 WITH 表的列时,WITH SQL 查询出错

Posted

技术标签:

【中文标题】约束 WITH 表的列时,WITH SQL 查询出错【英文标题】:WITH SQL Query gives error when constraining on WITH Table's column 【发布时间】:2020-10-02 17:18:03 【问题描述】:

这个查询有什么问题? (甲骨文)

with latestplans as (
    select plan_id, max(plan_last_changed_date) 
    from idp.trainee_search_vw 
    group by plan_id 
)
select plan_id, training_organization 
from idp.trainee_search_vw 
where plan_id in (latestplans.plan_id);

错误是:

ORA-00904:"LATESTPLANS"."PLAN_ID": invalid identifier

我正在定义一个临时表,其中包含视图中的一列和具有最大分组的另一列。然后,我需要在该临时表的列上进行选择。

目标是仅为最新计划选择某些属性,而视图最初列出所有计划。

内部查询有效。

【问题讨论】:

【参考方案1】:

你需要一个select:

plan_id in (select latestplans.plan_id from latestplans);

CTE 的行为类似于表或视图名称。你不能只使用它们而不在 from 子句中引用它们。

【讨论】:

【参考方案2】:

在您的查询中,您错过了对latestplans 的引用以及您对trainee_search_vw 的看法。

with latestplans as 
  (    select plan_id, max(plan_last_changed_date) from idp.trainee_search_vw 
group by plan_id )
select plan_id, training_organization 
from idp.trainee_search_vw as vw 
where exists (select 1 from latestplans where vw.plan_id=latestplans.plan_id);

【讨论】:

【参考方案3】:

已经解释了您使用 CTE 的方式存在什么问题。

不过,让我确定一下:

您的查询似乎没有按照您的描述进行:外部查询应该在最大日期而不是plan_id 上进行过滤;实际上,查询返回表的所有行

你不需要扫描表两次就能得到你想要的结果;你可以用窗函数解决这个每组最大 n 的问题

查询:

select plan_id, training_organization
from (
    select 
        t.*, 
        row_number() over(partition by plan_id order by plan_last_changed_date desc) rn
    from idp.trainee_search_vw t
) t
where rn = 1

您还可以使用聚合和 Oracle 的 keep 语法:

select 
    plan_id, 
    max(training_organization) 
        keep(dense_rank first order by plan_last_changed_date desc) training_organization
from idp.trainee_search_vw
group by plan_id

【讨论】:

【参考方案4】:
with latestplans as 
  (    select plan_id, max(plan_last_changed_date) max-plan_date
       from idp.trainee_search_vw 
       group by plan_id
   )

 select vw.plan_id, vw.training_organization,lp.max_plan_date
  from idp.trainee_search_vw vw
   Inner join  latestplans lp on lp.plan_id=vw.plan_id

另外,你可以在加入后使用 where

【讨论】:

以上是关于约束 WITH 表的列时,WITH SQL 查询出错的主要内容,如果未能解决你的问题,请参考以下文章

FMDB stringforcolumn with nil

如何使用SQL中的“With”子句更新值

跨多个表的列的 SQL 唯一约束

sql server 对已有数据的表,添加核查约束 [失败],请使用with nocheck 子句

SQL Server with ties 语句

MySQL的SQL语句 - 数据操作语句(17)- WITH 语句