2012-04-10 2 views
5

Как я могу ссылаться на столбец вне подзапроса с использованием Oracle? Мне нужно использовать его в инструкции WHERE для подзапроса.Справочный столбец родительского запроса в подзапросе (Oracle)

В принципе у меня есть это:

SELECT Item.ItemNo, Item.Group 
FROM Item 
    LEFT OUTER JOIN (SELECT Attribute.Group, COUNT(1) CT 
        FROM Attribute 
        WHERE Attribute.ItemNo=12345) A ON A.Group = Item.Group 
WHERE Item.ItemNo=12345 

Я хотел бы изменить WHERE Attribute.ItemNo=12345 к WHERE Attribute.ItemNo=Item.ItemNo в подзапрос, но я не могу понять, если это возможно. Я получаю "ORA-00904: 'Пункт' 'ITEMNO':. Недопустимый идентификатор"

EDIT:

Хорошо, вот почему мне нужен этот вид структуры:

Я хочу быть в состоянии получить количество записей «Ошибка» (где элемент отсутствует значение) и записи «ОК» (где элемент имеет значение).

Способ, которым я установил его в скрипке, возвращает правильные данные. Я думаю, что я мог бы просто заполнить значение в каждом из подзапросов, так как это, вероятно, было бы самым простым способом. Извините, если мои структуры данных немного запутаны. Я могу объяснить, если это необходимо.

Мои таблицы:

create table itemcountry(
    itemno number, 
    country nchar(3), 
    imgroup varchar2(10), 
    imtariff varchar2(20), 
    exgroup varchar2(10), 
    extariff varchar2(20)); 

create table itemattribute(
    attributeid varchar2(10), 
    tariffgroup varchar2(10), 
    tariffno varchar2(10)); 

create table icav(
    itemno number, 
    attributeid varchar2(10), 
    value varchar2(10)); 

и мой запрос до сих пор:

select itemno, country, imgroup, imtariff, im.error "imerror", im.ok "imok", exgroup, extariff, ex.error "exerror", ex.ok "exok" 
from itemcountry 
    left outer join (select sum(case when icav.itemno is null then 1 else 0 end) error, sum(case when icav.itemno is not null then 1 else 0 end) ok, tariffgroup, tariffno 
        from itemattribute ia 
        left outer join icav on ia.attributeid=icav.attributeid 
        where (icav.itemno=12345 or icav.itemno is null) 
        group by tariffgroup, tariffno) im on im.tariffgroup=imgroup and imtariff=im.tariffno 
    left outer join (select sum(case when icav.itemno is null then 1 else 0 end) error, sum(case when icav.itemno is not null then 1 else 0 end) ok, tariffgroup, tariffno 
        from itemattribute ia 
        left outer join icav on ia.attributeid=icav.attributeid 
        where (icav.itemno=12345 or icav.itemno is null) 
        group by tariffgroup, tariffno) ex on ex.tariffgroup=exgroup and extariff=ex.tariffno 
where itemno=12345; 

Он также создан в SQL Fiddle.

+0

Вы не можете .. что вы хотите выбрать? может иметь другое решение, отличное от внешнего внешнего соединения. – hkutluay

+0

см. Sqlfiddle – tedski

ответ

0

Вы можете сделать это в подзапросе, но не в соединении. В вашем случае я не вижу необходимости. Вы можете поместить его в состояние соединения.

select i.itemno, i.group 
    from item i 
    left outer join (select group, itemno 
         from attribute b 
        group by group itemno) a 
    on a.group = i.group 
    and i.itemno = a.itemno 
where i.itemno = 12345 

Оптимизатор предназначен для решения подобной ситуации, поэтому используйте его!

Я изменил count(1) на group by, так как вам нужно group by все столбцы, которые не агрегированы.

Я предполагаю, что ваш фактический запрос является более сложным, чем это, как со столбцами вы выбираете это, вероятно, equivilent к

select itemno, group 
    from item 
where itemno = 12345 

Вы также можете написать свой подзапрос с analytic function вместо этого. Что-то вроде count(*) over (partition by group).

В качестве альтернативы, используя ключевое слово в качестве имени столбца, в этом случае group - это плохая идея TM. Это может вызвать много путаницы. Как видно из приведенного выше кода, у вас много groups.


Итак, основываясь на вашем SQL-Скрипке, который я добавил на этот вопрос, я думаю, что вы ищете что-то вроде следующего, который не выглядит намного лучше.Я подозреваю, что, учитывая время, я мог бы сделать это проще. С другой стороны примечание явно ниже запросов на обсадную колонну никогда не стоит того хлопота, который он вызывает. Однако я придерживался вашего соглашения об именах.

with sub_query as (
select count(*) - count(icav.itemno) as error 
     , count(icav.itemno) as ok 
     , min(itemno) over() as itemno 
     , tariffgroup 
     , tariffno 
    from itemattribute ia 
    left outer join icav 
    on ia.attributeid = icav.attributeid 
    group by icav.itemno 
     , tariffgroup 
     , tariffno 
) 
    select ic.itemno, ic.country, ic.imgroup, ic.imtariff 
     , sum(im.error) as "imerror", sum(im.ok) as "imok" 
     , ic.exgroup, ic.extariff 
     , sum(ex.error) as "exerror", sum(ex.ok) as "exok" 
     from itemcountry ic 
     left outer join sub_query im 
     on ic.imgroup = im.tariffgroup 
     and ic.imtariff = im.tariffno 
     and ic.itemno = im.itemno 
     left outer join sub_query ex 
     on ic.exgroup = ex.tariffgroup 
     and ic.extariff = ex.tariffno 
     and ic.itemno = ex.itemno 
    where ic.itemno = 12345 
    group by ic.itemno, ic.country 
      , ic.imgroup, ic.imtariff 
      , ic.exgroup, ic.extariff 
      ; 
+0

Спасибо, я рассмотрю эти аналитические функции. Вы правы, я пытался как можно проще воссоздать пример. Лучшее представление о моей конечной цели - в sqlfiddle, который я добавил в редактировании. – tedski

+0

@tedski, мой ответ все еще стоит! Использование менее сложного примера - стандартная практика, что облегчает жизнь для всех. Вы можете поместить свое условие в соединение ... – Ben

+0

Извините, мой пример не отразил мою проблему правильно. В подзапросе есть еще одна таблица, и на самом деле есть два счета. У меня есть счет, когда элемент в объединенной таблице равен нулю, а когда нет. Если бы я добавил номер позиции в, он выплевывал бы два столбца вместо одного. – tedski

-4

В подзапросе можно указать атрибут WHERE.itemno = item.itemno. В любом случае вы будете фильтровать данные, и фильтрация данных внутри подзапроса также будет быстрее.

+0

Я не могу ... читать последний абзац. – tedski

+0

ОП указал, что это не работает в вопросе. – Ben

Смежные вопросы