2012-04-10 6 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=Item.ItemNoWHERE Attribute.ItemNo=12345を変更したいのですが、これは可能であるならば、私は理解することはできません。

は基本的に私はこれを持っています。私は得続ける "ORA-00904: '項目を' 'ITEMNO':無効な識別子"

EDIT:

私がしたい:私はこのような構造を必要とする理由

[OK]を、これは「エラー」レコード(アイテムに値がない場合)と「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 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 

オプティマイザは、このような状況に対処するために構築されています。

group byには集計されていないすべての列が必要なので、count(1)group byに変更しました。

あなたはこれを選択している列と同じように、私はあなたの実際のクエリがこれよりも複雑であることを仮定しているが、おそらくあなたはまた、代わりにanalytic functionを使用してサブクエリを書くことができ

select itemno, group 
    from item 
where itemno = 12345 

にequivilentです。 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

申し訳ありません、私の例は正しく問題をキャプチャしていませんでした。サブクエリには別のテーブルが結合されていますが、実際には2つのカウントがあります。私は、結合されたテーブルの項目がnullの場合とそうでない場合のカウントを持っています。で項目番号を追加すると、1つではなく2つの列が吐き出されます。 – tedski

-4

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

+0

私は最後の段落を読むことができません。 – tedski

+0

OPはこれが問題では機能しないことを示しています。 – Ben

関連する問題