【问题标题】:Cannot select a column from a subquery无法从子查询中选择列
【发布时间】:2018-12-15 03:35:09
【问题描述】:

我做了这个我需要的查询,但我只需要结果中的一列。所以它是这样的:

select SWDATECREATED from 
      (select * from MBR_INST_PRODUCTS
       inner join MBR_SUBSCRIBERS 
       on MBR_INST_PRODUCTS.SWOBJECTID = MBR_SUBSCRIBERS.SWSUBRID 
       where MBR_SUBSCRIBERS.SWSUBRID = 54501928
       and SWINSTPRODID = 1433193947);

如果我在括号内运行选择,那就太好了。 但是,如果我尝试从该结果集中仅选择特定列,则会收到错误 ORA-00904。 我已经检查了错误,但所有列都正确写入。 如何从选择中仅选择 SWDATECREATED?

这是我的错误:
ORA-00904: "SWDATECREATED": 无效标识符 00904. 00000 - "%s: 无效标识符" *原因:
*行动: 行错误:5 列:8

感谢您的宝贵时间。

【问题讨论】:

  • 。 .您需要清楚哪些查询有效,哪些无效。我很困惑。
  • 如果你只运行子查询,而不是使用*,你只选择SWDATECREATED,会发生什么?
  • 您说“所有列都写得正确”,但我只看到一列“已写”,其余列的选择让我们的疑难解答盲目,因为我们不知道 * 中选择了什么.在你的 SQL 中更加明确,也许问题和它的解决方案会自己出现。
  • 方括号中的内容:select * from MBR_INST_PRODUCTS 内部连接 ​​MBR_SUBSCRIBERS on MBR_INST_PRODUCTS.SWOBJECTID = MBR_SUBSCRIBERS.SWSUBRID 其中 MBR_SUBSCRIBERS.SWSUBRID = 54501928 和 SWINSTPRODID = 1433193947 给我一个结果行,但我只想要从该行获取 SWDATECREATED 列
  • @VictorG - 但结果集中有两列具有该名称,对吧?

标签: sql oracle subquery ora-00904


【解决方案1】:

你基本上有这样的情况,你在两个表中都有相同的列名(尽管你可能有比这更多的列):

create table MBR_INST_PRODUCTS (SWINSTPRODID, SWOBJECTID, SWDATECREATED) as
select 1433193947, 54501928, date '2018-01-01' from dual;

create table MBR_SUBSCRIBERS (SWSUBRID, SWDATECREATED) as
select 54501928, date '2018-02-28' from dual;

select * from MBR_INST_PRODUCTS
inner join MBR_SUBSCRIBERS 
on MBR_INST_PRODUCTS.SWOBJECTID = MBR_SUBSCRIBERS.SWSUBRID 
where MBR_SUBSCRIBERS.SWSUBRID = 54501928
and SWINSTPRODID = 1433193947;

SWINSTPRODID SWOBJECTID SWDATECREATED         SWSUBRID SWDATECREATED      
------------ ---------- ------------------- ---------- -------------------
  1433193947   54501928 2018-01-01 00:00:00   54501928 2018-02-28 00:00:00

在结果集中,您拥有两个表中的所有列,包括具有相同名称的列。客户端(本例中为 SQL Developer)正在显示原始列名,但有些人可能会将它们更改为唯一的。

当您尝试将该查询用作内联视图时,名称必须是唯一的,Oracle 会在内部隐式添加一些内容以使其唯一;它决定什么或如何决定并不重要。当你这样做时

select SWDATECREATED from ( .. that query ... )

内联视图中这两列的内部名称现在都与您期望看到的名称不匹配,因此您会得到 ORA-00904。该标识符确实存在于内联视图中。

您不需要子查询来仅获取该列,但您必须指定您想要的两列中的 哪一个 - 否则您将获得 ORA-00918,因为 Oracle 不能猜猜你指的是哪一个:

select MBR_INST_PRODUCTS.SWDATECREATED from MBR_INST_PRODUCTS
inner join MBR_SUBSCRIBERS 
on MBR_INST_PRODUCTS.SWOBJECTID = MBR_SUBSCRIBERS.SWSUBRID 
where MBR_SUBSCRIBERS.SWSUBRID = 54501928
and SWINSTPRODID = 1433193947;

SWDATECREATED      
-------------------
2018-01-01 00:00:00

select MBR_SUBSCRIBERS.SWDATECREATED from MBR_INST_PRODUCTS
inner join MBR_SUBSCRIBERS 
on MBR_INST_PRODUCTS.SWOBJECTID = MBR_SUBSCRIBERS.SWSUBRID 
where MBR_SUBSCRIBERS.SWSUBRID = 54501928
and SWINSTPRODID = 1433193947;

SWDATECREATED      
-------------------
2018-02-28 00:00:00

如果您有其他理由使用子查询,那么您需要以相同的方式指定要从哪个表中获取该列,可选择包括其他列;或包括两列但给它们唯一的别名。然后,您将能够在外部查询中引用别名。


使用* 通常被认为是不好的做法,尤其是在子查询中,部分原因是它可能会导致不必要的工作量,部分原因是您可能会被代码运行之间的表更改绊倒,部分原因是它可能会导致这种混乱。

最好明确命名您想要的列;并为 all 列加上它们来自的表(或表别名),即使它们是唯一的,这样您和任何必须维护代码的人都可以更轻松地遵循它;我不得不猜测将SWINSTPRODID 列放入哪个表中。这也更安全 - 以防万一以后将新列添加到表中,使其不唯一。

【讨论】:

  • 哇,你刚跑完 9 码 :) 我真的很感谢你花时间向我解释内部工作原理,我现在真的明白这一点,也许更多。非常感谢你!互联网很棒。
【解决方案2】:

您应该在查询中使用它作为列名:

select SWDATECREATED from MBR_INST_PRODUCTS
   inner join MBR_SUBSCRIBERS 
   on MBR_INST_PRODUCTS.SWOBJECTID = MBR_SUBSCRIBERS.SWSUBRID 
   where MBR_SUBSCRIBERS.SWSUBRID = 54501928
   and SWINSTPRODID = 1433193947;

【讨论】:

  • 我已经尝试过这个 SurfMan 但我得到 ORA-00918: column ambiguously defined.
  • @VictorG - 那么它存在于两个表中,你需要在它前面加上你想要实际从中获取值的表名。
  • @AlexPoole 所说的:使用表名:MBR_INST_PRODUCTS.SWDATECREATED(如果两列包含相同的数据,那并不重要,但您应该小心选择正确的)
  • 没错,它在两个表中。我给它加上了前缀,现在我得到了正确的答案。谢谢大家!!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-04
  • 2012-02-13
  • 1970-01-01
  • 1970-01-01
  • 2014-11-23
相关资源
最近更新 更多