8

Oracleを使用してサブクエリの外部の列を参照するにはどうすればよいですか?特に、サブクエリのWHEREステートメントで使用する必要があります。

基本的に私はこれを持っています:

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:'Item'。'ItemNo':InvalidIdentifier」が表示され続けます

編集:

わかりました、これが私がこの種の構造を必要とする理由です:

「エラー」レコード(アイテムに値がない場合)と「OK」レコード(アイテムに値がある場合)のカウントを取得できるようにしたい。

私がフィドルで設定した方法では、正しいデータが返されます。これがおそらく最も簡単な方法であるため、各サブクエリに値を入力することになるかもしれないと思います。私のデータ構造が少し複雑な場合は申し訳ありません。必要に応じて説明できます。

私のテーブルは次のとおりです。

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フィドルでも設定されています。

4

2 に答える 2

1

サブクエリでは実行できますが、結合では実行できません。あなたの場合、その必要はないと思います。結合状態に入れることができます。

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)を aに変更しました。group bygroup by

実際のクエリはこれよりも複雑であると想定しています。これは、選択している列がおそらく同等であるためです。

select itemno, group
  from item
 where itemno = 12345

代わりにサブクエリを書くこともできますanalytic function。のようなものcount(*) over ( partition by group)

列名としてキーワードを使用することはさておき、この場合groupは A Bad Idea TMです。それは多くの混乱を引き起こす可能性があります。上記のコードからわかるようにgroups、そこにはたくさんのものがあります。


したがって、質問に追加した SQL-Fiddle に基づいて、次のようなものを探していると思いますが、これはあまり良くありません。時間があれば、もっと簡単にできると思います。別の側面として、明示的に小文字のクエリを使用することは、それが引き起こす手間に見合う価値はありません。ただし、命名規則に従いました。

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
           ;
于 2012-04-10T18:15:56.087 に答える
-4

サブクエリ内に WHERE attribute.itemno=item.itemno を入れることができます。とにかくデータをフィルタリングします。通常、サブクエリ内のデータをフィルタリングする方が高速です。

于 2012-04-10T16:40:34.877 に答える