web-dev-qa-db-ja.com

WHERE句を使用したLEFT OUTER JOIN

2つのテーブルがあります。 indRailTypeには、他のテーブルでレールタイプを示すために使用するID値とペアになっている名前のリストが含まれています。 WO_BreakerRailには、indRailTypeおよびその他のデータの同じコードに対応する日付列と鉄道コード列が含まれます。 WO_BreakerRailには、各レールタイプ、日付ごとのアクティビティの行があります。したがって、3/19/2010の日付が3行ある可能性があります。各行は異なる鉄道コードと何が起こったかを示しています。

次のLEFT OUTER JOINを使用すると、19日に何も起こらなかった行にヌルが含まれる、すべてのタイプのレールを含むテーブルが取得されます。現時点では、WO_BreakerRailテーブルに表されている日付は19日だけなので、これは機能しています。日付の異なる行を追加すると、物事がうまくいきません。

これが私のSQLステートメントであり、現在、必要な結果を正確に提供しています。

SELECT WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces, 
    WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged, 
    WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop
FROM indRailType
LEFT OUTER JOIN WO_BreakerRail 
    ON indRailType.RailCode = WO_BreakerRail.RailCode

WHERE WO_BreakerRail.Date = @Date句を追加すると、JOINのすべての行が失われ、何も起こりませんでした。私はそれを望んでいません。読んでみると、FULL OUTER JOINが欲しいのですが、SQL Server Compact EditionはFULL OUTER JOINsをサポートしていません。これを回避する方法はありますか、それともまったく別のものを探していますか?

21
Wesley

試してください:

SELECT WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces, 
    WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged,
    WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop
FROM indRailType
LEFT OUTER JOIN WO_BreakerRail ON indRailType.RailCode = WO_BreakerRail.RailCode 
            AND WO_BreakerRail.Date = @Date

したがって、AND WO_BreakerRail.Date = @Date参加する

40
Philip Fourie

述部条件は、where句ではなく、結合のOn句に含まれている必要があります。外部結合が機能する方法は、結合条件が分析された後、内側と一致しない「外側」のすべての行が再び追加されます。しかし、これはすべてwhere句が処理される前に発生します。そのため、where句の述語が外部結合の外側からの属性をフィルター処理すると、それらの行はすべて削除されます(すべてNULLです)。代わりに、述語を結合条件に入れると、欠落した行が再び追加される前に評価されます...

SELECT b.ID, t.RailType, b.CreatedPieces, 
       b.OutsideSource, b.Charged, b.Rejected, 
       b.RejectedToCrop 
FROM indRailType t
   LEFT JOIN WO_BreakerRail b
        ON t.RailCode = b.RailCode 
            And b.Date = @Date
15
Charles Bretana

次のwhere句を使用できます。

WHERE WO_BreakerRail.Date = @Date OR WO_BreakerRail.Date IS NULL
5
Andrew Bezzub

WHEREではなく、_WO_BreakerRail.Date = @Date_ステートメントに_LEFT OUTER JOIN_を追加します。

_SELECT
    WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces, WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged, WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop
    FROM indRailType 
        LEFT OUTER JOIN WO_BreakerRail ON indRailType.RailCode = WO_BreakerRail.RailCode AND WO_BreakerRail.Date = @Date
_

または、WHEREに追加できます。

_SELECT
    WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces, WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged, WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop
    FROM indRailType 
        LEFT OUTER JOIN WO_BreakerRail ON indRailType.RailCode = WO_BreakerRail.RailCode
    WHERE (WO_BreakerRail.Date = @Date OR WO_BreakerRail.Date IS NULL)
_
2
KM.

または、WHEREに追加できます:

SELECT WO_BreakerRail.ID, indRailType.RailType, 
  WO_BreakerRail.CreatedPieces, 
  WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged, 
  WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop 
FROM indRailType, WO_BreakerRailCode 
WHERE indRailType.RailCode = WO_BreakerRail.RailCode(+) 
 AND WO_BreakerRail.Date (+) =@Date 
1
Nilanjan Pal

必要なのは、WO_BreakerRail希望の日付にbefore LEFT JOINing to indRailType。 WHEREステートメントを追加するだけの場合は、逆の方法で実行され、説明した問題が発生します。

これまでに提供されたソリューションは機能するはずです(条件をLEFT JOINに移動します)が、別の方法を提案したいと思います。サブクエリを使用して、実行する順序を指定できます。

SELECT R.ID, indRailType.RailType, R.CreatedPieces, R.OutsideSource, R.Charged, R.Rejected, R.RejectedToCrop
  FROM indRailType LEFT OUTER JOIN
       (SELECT * FROM WO_BreakerRail WHERE Date = @Date) R
       ON indRailType.RailCode = R.RailCode

(テストされていませんが、私が知る限り、SQL Server CEはサブクエリをサポートしています。)

1
Heinzi