Невозможно выбрать столбец из подзапроса

Я сделал этот запрос, который мне нужен, но мне нужен только один столбец из результата. Итак, это выглядит так:

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 ответа

По сути, у вас есть такая ситуация, когда у вас одинаковые имена столбцов в обеих таблицах (хотя, вероятно, у вас больше столбцов, чем эта):

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

Если у вас есть другая причина для использования подзапроса, вам нужно либо указать, из какой таблицы вы хотите этот столбец, таким же образом, необязательно включая другие столбцы; или включить оба столбца, но дать им уникальные псевдонимы. После этого вы сможете ссылаться на псевдонимы во внешнем запросе.


Часто считается плохой практикой *особенно в подзапросе, отчасти потому, что это может привести к большему количеству работы, чем необходимо, отчасти потому, что вы можете запутаться из-за изменений таблиц между запусками кода, а отчасти потому, что это может вызвать путаницу такого рода.

Лучше явно назвать столбцы, которые вы хотите; и префикс всех столбцов с таблицей, из которой они исходят (или псевдоним таблицы), даже если они уникальны, так что вы и любой, кто должен поддерживать код, могут легче следовать за ним; Я должен был угадать, какую таблицу поставить SWINSTPRODID столбец в. Это также безопаснее - на случай, если новый столбец будет добавлен в таблицу позже, что делает его неуникальным.

Вы должны просто использовать это как имя столбца в запросе:

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;
Другие вопросы по тегам