简体   繁体   中英

Cannot select a column from a subquery

I made this query that i need but i need only one column from the result. So it goes like this:

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

If i run the select within the brackets it`s good. But if i try to select only a specific column from that result set i get error ORA-00904. I checked the error already but all the columns are written correctly. How can i select only SWDATECREATED from the select?

Here`s my error:
ORA-00904: "SWDATECREATED": invalid identifier 00904. 00000 - "%s: invalid identifier" *Cause:
*Action: Error at Line: 5 Column: 8

Thank you for your time.

You basically have a situation like this, where you have the same column names in both tables (though presumably you have more columns than this):

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

In the result set you have all the columns from both tables, including those with the same name. The client (SQL Developer in this case) is displaying the original column names, but some might change them to be unique.

When you try to use that query as an inline view the names have to be unique, and Oracle is implicitly adding something internally to make them unique; it doesn't really matter what or how it decides. When you do

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

neither internal name for those two columns in the inline view now matches the one you expect to see, so you get an ORA-00904. That identifier does not exist in the inline view.

You don't need a subquery to get just that column, but you have to specify which of the two columns you want - otherwise you'll get an ORA-00918 since Oracle can't guess which one you meant:

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

If you have another reason to use a subquery then you either need to specify which table you want that column from in the same way, optionally including other columns; or include both columns but give them unique aliases. You will then be able to refer to the alises in the outer query.


It's often considered bad practice to use * , particularly in a subquery, partly because it can cause more work than necessary to be done, partly because you can be tripped up by table changes between code runs, and partly because it can cause this sort of confusion.

It's better to explicitly name the columns you want; and to prefix all columns with the table they are coming from (or a table alias) even if they are unique, so you and anyone who has to maintain the code can follow it more easily; I had to guess which table to put the SWINSTPRODID column in. It's also safer - just in case a new column is added to a table later which makes it non-unique.

You should just use that as columnname in the query:

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM