无法从子查询中选择列

时间:2018-07-06 13:46:50

标签: sql oracle subquery ora-00904

我进行了此查询,但结果只需要一列。就像这样:

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);

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

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

谢谢您的时间。

2 个答案:

答案 0 :(得分:3)

您基本上会遇到这样的情况,即两个表中的列名都相同(尽管可能您拥有的列数比这还多):

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。内嵌视图中不存在该标识符。

您不需要子查询来获取该列,但是您必须在想要的两列中指定哪一个-否则由于Oracle无法获得ORA-00918猜猜你的意思是

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列。它也更安全-以防万一稍后将新列添加到表中使其不唯一。

答案 1 :(得分:1)

您应该在查询中将其用作列名:

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;