web-dev-qa-db-ja.com

左外部結合が機能しない?

両方の結合にLEFT OUTER JOINを使用して、3つのテーブルからデータをプルするクエリがあります。右側の2つのテーブル(それぞれ処方者と処方箋)に対応するデータがない場合でも、左端(Salesrepテーブル)の情報を返すクエリが必要です。 WHERE句に日付パラメーターを指定せずにこのクエリを実行すると、期待どおりの結果が得られますが、日付パラメーターを含めると、salesrepに一致するデータがない場合は何も返されません。クエリで要求されたsalesrepテーブルの列を少なくとも表示する必要があります。

ここにクエリがあります...どんな助けも非常に高く評価されています。

SELECT  salesrep.salesrepid as SalesRepID,
        salesrep.fname as SalesrepFName,
        salesrep.lname as SalesRepLName,
        salesrep.fname+' '+salesrep.lname as SalesRepFullName,
        prescriber.dea_no as PDeaNo,
        prescriber.lname+', '+prescriber.fname as DocName,
        CONVERT(VARCHAR(8), prescriptions.filldate, 1) as FillDate,
        prescriptions.drugname as DrugName,
        prescriptions.daysupply as Supply,
        prescriptions.qtydisp as QtyDisp,
        prescriptions.rx_no as Refill,
        prescriptions.copay as Sample,
        ROUND(prescriptions.AgreedToPay-(prescriptions.AgreedToPay*.07),2) as AgreedToPay,
        prescriptions.carrierid as CarrierID
FROM    salesrep
  LEFT OUTER JOIN prescriber on salesrep.salesrepid = prescriber.salesrepid
  LEFT OUTER JOIN prescriptions on prescriber.dea_no = prescriptions.dea_no
  WHERE salesrep.salesrepid = 143 AND
        prescriptions.filldate >= '09-01-12' AND
        prescriptions.filldate <= '09-17-12'
ORDER BY prescriptions.filldate
32
jgiven

prescriptions.filldateの制約を結合のON条件に移動し、where句から削除する必要があります。

LEFT OUTER JOIN prescriptions ON prescriber.dea_no = prescriptions.dea_no
                             AND prescriptions.filldate >= '09-01-12'
                             AND prescriptions.filldate <= '09-17-12'

それ以外の場合、prescriptionsがないエントリはprescriptions.filldate内のnullsになり、WHERE句はそれらを破棄します。

67
dasblinkenlight

ここ クエリ処理フェーズに関する簡単な説明があります(ほとんどのDBMSで一般的です)。 OUTER JOINの場合、次のことがわかります。

  1. 最初のCARTESIAN JOINが作成され、
  2. 行のサブセットを生成する結果セットでON条件が実行されるよりも、
  3. 外側の行よりも内側のテーブルの結合列にNULLが追加された後、
  4. その結果に対して、フィルタリングを実行するWHERE句が適用されます。

外部テーブルの行に触れるWHERE句内に条件を配置すると、それらはすべて破棄されます。この条件は、外側の行が追加される前に評価されるため、単にON句内に配置する必要があります。

したがって、それらの条件:

prescriptions.filldate >= '09-01-12' AND
prescriptions.filldate <= '09-17-12'

oN句に移動する必要があります。

14
WojtusJ

これは、prescriptions.filldate不等式により、prescriptions.filldate列に値がないsalesrep行が除外されているためです。

したがって、null値(右側のテーブルに一致するデータがない)がある場合、salesrepデータを含む行全体が日付フィルターによって除外されます-nullは2つの日付の間にないためです。

0
xelco52