2

古い ASP ファイルを新しい .NET 2.0 コードに複製する際に問題が発生しました。タスクの 1 つは、4 ~ 5 個の SQL ステートメントを 1 つにマージすることです。私はこれを行い、パフォーマンスの向上にある程度成功しましたが、Oracle は私にとって新しいバッグです。ただし、この問題は、これまで行ったことがないため、自分の SQL スキルを超えています。

基本的に、私はたくさんの Sales から 1 つのテーブルに QUANTITY を持っています。各売上には整数値があります。各セールには ITEM が添付されています。各 ITEM には、何かの 1 袋 = 何かの 10 束を販売するかのように、変換係数があります。したがって、レポートを実行して最終値を知りたい場合は、各売上とその数量を取得し、換算係数で乗算する必要があります。ほとんどが単純な 1 対 1 なので、基本的には 25*1、30*1 などを行っています。

私の問題は、アイテムがシステムから削除された過去の販売が記録にあるため、CONVERSION ファクターが存在しないことです。FACTOR がなくなったため、これらのレコードはクエリから削除されます。

SELECT rth.CODE, rth.NUMBER, rth.QUANTITY, rth.sale_code 
FROM salesdetails rth, salesheader rsh
WHERE rsh.number = rth.number(+)
AND rsh.customer_code = '05'
AND rsh.r_code = '01'
AND rsh.location_code = '12'
AND rth.sale_code IN('ITEM07')
AND rth.c_code = 'WLMT'
AND rsh.year = '2008'

これは私の最初のクエリです。変換を追加すると:

SELECT rth.CODE, rth.NUMBER, rth.QUANTITY, rth.sale_code, rth.quantity * cf.conversion
FROM salesdetails rth, salesheader rsh, conversionfactor cf
WHERE rsh.number = rth.number(+)
AND rsh.customer_code = '05'
AND rsh.r_code = '01'
AND rsh.location_code = '12'
AND rth.sale_code IN('ITEM07')
AND rth.c_code = 'WLMT'
AND rsh.year = '2008'
AND cf.item_code = rth.item_code
and cf.code = '01'
and cf.loc_code = '00001'

これはある程度機能します。同じレコードがすべてリストされていますが、CONVERSION 因子が存在しなかったレコードはありません。とにかく、FACTORが2番目のクエリに存在しなかったレコードを含めることができます.1行ずつ行ってそのように変換することはできません.

4

9 に答える 9

2

サブクエリで Coalesce 関数を使用することもできます...

< Coalesce(arg0, arg1, arg2, ..... など argN)

各引数を順番に評価し、Null ではない最初の引数を返します。>

Select D.CODE, D.NUMBER, D.QUANTITY, D.sale_code, 
    D.quantity * Coalesce((Select conversion 
                           From conversionfactor
                           Where item_code = H.item_code
                              And code = '01'
                              And loc_code = '00001'), 1.0)
From salesheader H
   Left Join salesdetails D
     On D.Number = H.Number
Where H.customer_code = '05'
   And H.r_code = '01'
   And H.location_code = '12'
   And H.year = '2008'
   And D.sale_code In ('ITEM07')
   And D.c_code = 'WLMT'

サブクエリの最後の 1.0 を、レコードが conversionfactor テーブルに存在しなくなったときに変換係数の「デフォルト」値にしたいものに置き換えます...

于 2008-11-18T16:33:39.067 に答える
1

rsh から rthへの外部結合は意味がありませんが、rth から cf への内部結合は意味がありません。それらを両方とも外部結合にします。また、(+) 記号は、rth のすべての結合条件の「外側」側に表示する必要があります。

SELECT rth.CODE, rth.NUMBER, rth.QUANTITY, rth.sale_code,
       rth.quantity * cf.conversion
FROM salesdetails rth, salesheader rsh, conversionfactor cf
WHERE rsh.number = rth.number(+)
AND rsh.customer_code = '05'
AND rsh.r_code = '01'
AND rsh.location_code = '12'
AND rth.sale_code (+) IN('ITEM07')
AND rth.c_code (+) = 'WLMT'
AND rsh.year = '2008'
AND cf.item_code (+) = rth.item_code
and cf.code (+) = '01'
and cf.loc_code (+) = '00001'

ちなみに、これは非常に古い構文です。より現代的なものを使用しない理由:

SELECT rth.CODE, rth.NUMBER, rth.QUANTITY, rth.sale_code,
       rth.quantity * cf.conversion
FROM salesheader rsh
LEFT OUTER JOIN salesdetails rth
   ON  rsh.number = rth.number
   AND rth.sale_code IN ('ITEM07')
   AND rth.c_code = 'WLMT'
LEFT OUTER JOIN conversionfactor cf
   ON  cf.item_code = rth.item_code
   AND cf.code = '01'
   AND cf.loc_code = '00001'
WHERE rsh.customer_code = '05'
AND rsh.r_code = '01'
AND rsh.location_code = '12'
AND rsh.year = '2008'
于 2008-11-18T16:28:45.100 に答える
0

現在、Oracleにアクセスできません。このクエリをチェックしてください:

SELECT rth.CODE, rth.NUMBER, rth.QUANTITY, rth.sale_code, rth.quantity * cf.conversion
FROM salesdetails rth, salesheader rsh, conversionfactor cf
WHERE rsh.number = rth.number(+)
AND rsh.customer_code = '05'
AND rsh.r_code = '01'
AND rsh.location_code = '12'
AND rth.sale_code IN('ITEM07')
AND rth.c_code = 'WLMT'
AND rsh.year = '2008'
AND rth.item_code  =  cf.item_code (+)
and cf.code = '01'
and cf.loc_code = '00001'
于 2008-11-18T16:10:44.713 に答える
0

いいえ、レコードが実際に存在しないため、OUTERJOINは機能しないと思います。nullではなく、もう存在しないだけです。

于 2008-11-18T16:14:57.077 に答える
0

私はそれがうまくいくはずだと思います。変換係数が存在しない場合、変換係数は1に等しいと想定します。

select 
    rth.code, rth.number, rth.quantity, rth.sale_code, rth.quantity * coalesce(cf.conversion,1)
from 
    salesdetails rth
    inner join  salesheader rsh on rsh.number = rth.number
    left join conversionfactor cf on cf.item_code = rth.item_code
where 
rsh.customer_code = '05'
and rsh.r_code = '01'
and rsh.location_code = '12'
and rth.sale_code in('item07')
and rth.c_code = 'wlmt'
and rsh.year = '2008'
and cf.code = '01'
and cf.loc_code = '00001'
于 2008-11-18T16:16:27.963 に答える
0

SQL は、null レコードがあると想定していると思います。いいえ、変換が存在しない場合の記録はまったくありません。DB に存在しない CONVERSION に対して null を返す方法を見つけることができれば、それを行うことができます。

于 2008-11-18T16:23:46.857 に答える
0

null 値を掛けようとしているために、レコードが失われていると思います。変換係数で NVL() を使用して、デフォルトの 1 またはその他の適切なデフォルト値に設定することを検討してください。

お気に入り、

SELECT rth.CODE, rth.NUMBER, rth.QUANTITY, rth.sale_code, rth.quantity * NVL(cf.conversion,1)
FROM salesdetails rth, salesheader rsh, conversionfactor cf
WHERE rsh.number = rth.number(+)
AND rsh.customer_code = '05'
AND rsh.r_code = '01'
AND rsh.location_code = '12'
AND rth.sale_code IN('ITEM07')
AND rth.c_code = 'WLMT'
AND rsh.year = '2008'
AND cf.item_code = rth.item_code
and cf.code = '01'
and cf.loc_code = '00001'

ただし、NVL 構文を再確認してください。オラクルで働いてから数年になります。

于 2008-11-20T04:38:23.987 に答える
0

実際、あなたは OUTER JOIN について正しいです。私はそれがやっていることには専門性があると思っていましたが、それでも値が含まれていなかった理由が正確にわかりました. NULL を含めるには、他の 2 つの基準を (+) にする必要がありました。それを COALESCE と組み合わせたところ、機能しているようです。

于 2008-11-18T16:45:57.717 に答える
0

null値と数値を扱う場合は、リストから最初の非null値が結果として返される「合体」関数の使用を検討してください。

于 2013-09-28T13:39:48.483 に答える