2016-06-20 32 views
0

次のスクリプトを使用して基本情報を返します。このスクリプトは、私は私の選択にしてLISTAGGを追加するときに、報告書はわずか55行を返し、65行(予想通り)...Oracle SQL:listaggの結果がないときにnull値を返します。

select unique 
     trunc(li.cre_dat) cre_date, 
     li.cre_usr, 
     li.catnr, 
     li.av_part_no, 
     li.artist, 
     li.title, 
     li.prodtyp, 
     li.packtyp, 
     nvl(sp.name_for_customer,sp.name) pack_type 
from leos_item li, 
     scm_packtyp sp 
where li.cunr in ('816900','816901','816902') 
and li.item_type = 'FP' 
and li.av_part_no is null 
and trunc(li.cre_dat) >= '01-JAN-2016' 
and li.model_force_creation_idc != 'Y' 
and li.i_status != 'I' 
and li.packtyp = sp.packtyp 

を返す...しかし。 10行にはlistaggの結果がないため、結果から省略されます。

select unique 
     trunc(li.cre_dat) cre_date, 
     li.cre_usr, 
     li.catnr, 
     li.av_part_no, 
     li.artist, 
     li.title, 
     li.prodtyp, 
     li.packtyp, 
     nvl(sp.name_for_customer,sp.name) pack_type, 
     regexp_replace(listagg(nvl(bom.av_part_no,'No'), ', ') 
     within group (order by bom.item_id),'([^,]+)(,\1)+', '\1') masters 
from leos_item li, 
     scm_packtyp sp, 
     TABLE(leos_flatbom_pkg.GetFlatBOM(li.item_id)) bom, 
     leos_item li1 
where li.cunr in ('816900','816901','816902') 
and li.item_type = 'FP' 
and li.av_part_no is null 
and trunc(li.cre_dat) >= '01-JAN-2016' 
and li.model_force_creation_idc != 'Y' 
and li.i_status != 'I' 
and li.packtyp = sp.packtyp 
and bom.item_id = li1.item_id 
and li1.item_type = 'MT' 
group by li.cre_dat, 
     li.cre_usr, 
     li.catnr, 
     li.av_part_no, 
     li.artist, 
     li.title, 
     li.prodtyp, 
     li.packtyp, 
     nvl(sp.name_for_customer,sp.name) 

しかし、これらの行も参照する必要があります。 listaggの結果が見つからない場合に10行を返す方法があります。私は、ヌルとnvlの以下の組み合わせを試しましたが、運がありません。

nullif(regexp_replace(listagg(nvl(bom.av_part_no,'No'), ', ') within group (order by bom.item_id),'([^,]+)(,\1)+', '\1'),'No Master') 

nvl(regexp_replace(listagg(nvl(bom.av_part_no,'No'), ', ') within group (order by bom.item_id),'([^,]+)(,\1)+', '\1'),'No Master') 
+0

あなたがトンで、おそらくいくつかのサンプルデータをポスト構築または小さなテーブル定義することができますあなたの問題を示す文を挿入するものはほとんどありません。私はhr employeesテーブルで小さなlistaggを試して、nullが返されました。部門番号を にして を にグループ (注文番号hire_date、last_name)を入力してください。 –

答えて

1

問題は、それはあなたが、内側はleos_flatbom_pkg.GetFlatBOM(li.item_id)ためTABLEコレクション式に参加し、親行が結果からフィルタリングされ、その結果がゼロの行が含まれて実行されていることであるLISTAGGではありません。

相関サブクエリで、このようなものに交換してください:他のいくつかのポイント

select unique 
     trunc(li.cre_dat) cre_date, 
     li.cre_usr, 
     li.catnr, 
     li.av_part_no, 
     li.artist, 
     li.title, 
     li.prodtyp, 
     li.packtyp, 
     nvl(sp.name_for_customer,sp.name) pack_type, 
     (SELECT regexp_replace(listagg(nvl(bom.av_part_no,'No'), ', ') 
        within group (order by bom.item_id),'([^,]+)(,\1)+', '\1') 
     FROM TABLE(leos_flatbom_pkg.GetFlatBOM(li.item_id)) bom 
       INNER JOIN leos_item li1 
       ON (bom.item_id = li1.item_id) 
     WHERE li1.item_type = 'MT' 
     ) masters 
from leos_item li 
     INNER JOIN 
     scm_packtyp sp 
     ON (li.packtyp = sp.packtyp) 
where li.cunr in ('816900','816901','816902') 
and li.item_type = 'FP' 
and li.av_part_no is null 
and li.cre_dat >= DATE '2016-01-01' 
and li.model_force_creation_idc != 'Y' 
and li.i_status != 'I' 

を:

  • ANSI結合構文を使用するように変更してください。古いOracleのカンマ区切り構文では、結合条件がWHERE句に埋め込まれているため、列がどのように結合されているか(特に外部結合の場合)はわかりにくいです。
  • 日付に文字列リテラルを使用しない(つまり'01 -JAN-2016 ')Oracleでは、NLS_DATE_FORMATセッション・パラメータをフォーマット・マスクとして暗黙的にTO_DATE()を実行し、これが変更された場合、クエリのテキストを変更する)、それはデバッグするのに苦労します。さらに悪いことに、これはセッションパラメータなので、1人のユーザーがそれを変更することは可能であり、その後は他のユーザーにとって効果的です。日付リテラル(例:DATE '2016-01-01')を使用するか、明示的にTO_DATE()と呼び出し、フォーマットマスクを入力してNLSの設定を修正してください。
  • li.cre_dat >= TRUNC(li.cre_dat)TRUNC(li.cre_dat) >= DATE '2016-01-01'が真ならば、li.cre_dat >= DATE '2016-01-01'も真です。あなたはTRUNC()コールを取り除くことができます。

また、あなたの2番目のクエリを使用してOUTER JOINするTABLEコスプレイ@ダイナミックセーラー式を変換し、それを解決することができます:

from leos_item li 
     scm_packtyp sp, 
     TABLE(leos_flatbom_pkg.GetFlatBOM(li.item_id)) (+) bom, 
     leos_item li1 
where ... 
and li.packtyp = sp.packtyp 
and li1.item_id = bom.item_id (+) 
+0

すべてのポイントが理解され、取られています。多くのおかげで、完璧に動作します! – SMORF

関連する問題