Невозможно выбрать столбец из подзапроса - PullRequest
0 голосов
/ 06 июля 2018

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

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 голосов
/ 06 июля 2018

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

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. Это также безопаснее - на случай, если новый столбец будет добавлен в таблицу позже, что сделает его неуникальным.

0 голосов
/ 06 июля 2018

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

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...