【问题标题】:Oracle subquery invalid identifierOracle 子查询无效标识符
【发布时间】:2020-10-15 18:51:16
【问题描述】:

我不知道这个查询有什么问题:

select * from inv_srv_inst inst, 
(select srvc.li_srv_cat_id from inv_li_srv_cat_srv srvc where srvc.srv_id = inst.service_id) li_srv_cat_id
where id in (37336558,37343286)

错误信息:

ORA-00904: "INST"."SERVICE_ID": 无效标识符 00904. 00000 - "%s: 无效标识符"

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    ORA-00904: "INST"."SERVICE_ID": 无效标识符

    您收到此错误是因为 INV_SRV_INST 不在内联视图的范围内。如果您使用的是 12c 或更高版本,您可以使用 LATERAL 关键字解决此问题,这允许我们将谓词推送到子查询中:

    select * 
    from inv_srv_inst inst, 
    lateral (select srvc.li_srv_cat_id 
             from inv_li_srv_cat_srv srvc 
             where srvc.srv_id = inst.service_id) li_srv_cat_id
    where id in (37336558,37343286)
    

    尽管必须要问,为什么选择内联视图而不是仅仅连接两个表?

    select inst.* 
           ,srvc.li_srv_cat_id 
    from inv_srv_inst inst
    inner join  inv_li_srv_cat_srv srvc 
    on srvc.srv_id = inst.service_id
    where inst.id in (37336558,37343286)
    

    这里是a demo on db<>fiddle

    【讨论】:

    • 我已经通过加入解决了这个问题。但是,sql server(我来自的dbms)支持这个。
    • 是的,您会发现两者在 SQL 实现上存在一些差异。
    【解决方案2】:

    永远不要FROM 子句中使用逗号。

    在您的情况下,您可以使用横向连接或相关子查询来表达这一点——假设只有一个匹配项。

    select *
    from inv_srv_inst inst cross join lateral
         (select srvc.li_srv_cat_id 
          from inv_li_srv_cat_srv srvc
          where srvc.srv_id = inst.service_id
         ) li_srv_cat_id
    where inst.id in (37336558, 37343286);
    

    横向连接非常方便。它们类似于相关子查询,但它们可以返回多列和多行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-12
      • 2010-12-20
      • 1970-01-01
      • 1970-01-01
      • 2019-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多