web-dev-qa-db-ja.com

Where句を使用した完全外部結合

両方のテーブルからすべてのレコードを返す方法が必要です[〜#〜] but [〜#〜] where条件がありますZT1以下の両方のクエリを試しましたが、クエリ1はZT1に存在しない@TTBLの行を無視しますが、クエリ2はテーブルZT1に配置するWHERE条件を無視します(bcがorに変更されたため)

@TTBLからのすべてのデータと日付基準の間にあるZT1からのデータのみの望ましい結果を達成するために、クエリをどのように記述する必要がありますか

    Query 1
SELECT
    Employee = COALESCE(ZT1.Employee,Z.Name),
    COUNT(ZT1.sales) AS Salecount,
    SUM(ISNULL(ZT1.[SaleTotal],0)) AS SaleTotal,
    SUM(ISNULL(ZT1.[SaleTotal],0) - ISNULL(ZT1.[TotalB4Discount],0)/NULLIF(ZT1.[SaleTotal],0)) AS ActualSale,
    SUM(ISNULL(ZT1.[SaleTotal],0) - ISNULL(ZT1.[TotalB4Discount],0)) AS ProfitMargin,
    ISNULL(Z.SaleTotal0,0) AS SaleTotal0,
    ISNULL(Z.SaleTotal1,0) AS SaleTotal1
FROM dbo.holdings AS ZT1
FULL OUTER JOIN @TTBL AS Z ON Z.Name = ZT1.Employee
WHERE ZT1.[SaleDate] >= '20170601'
AND ZT1.[SaleDate] <= '20170625'
GROUP BY ZT1.Employee,Z.SaleTotal0,Z.SaleTotal1,Z.Name

--Query 2
SELECT
    Employee = COALESCE(ZT1.Employee,Z.Name),
    COUNT(ZT1.sales) AS Salecount,
    SUM(ISNULL(ZT1.[SaleTotal],0)) AS SaleTotal,
    SUM(ISNULL(ZT1.[SaleTotal],0) - ISNULL(ZT1.[TotalB4Discount],0)/NULLIF(ZT1.[SaleTotal],0)) AS ActualSale,
    SUM(ISNULL(ZT1.[SaleTotal],0) - ISNULL(ZT1.[TotalB4Discount],0)) AS ProfitMargin,
    ISNULL(Z.SaleTotal0,0) AS SaleTotal0,
    ISNULL(Z.SaleTotal1,0) AS SaleTotal1
FROM dbo.holdings AS ZT1
FULL OUTER JOIN @TTBL AS Z ON Z.Name = ZT1.Employee
OR ZT1.[SaleDate] >= '20170601'
AND ZT1.[SaleDate] <= '20170625'
GROUP BY ZT1.Employee,Z.SaleTotal0,Z.SaleTotal1,Z.Name

このクエリを試してみてください。 "WHERE"句は完全な外部結合を正しい結合に効果的に変換していると思います。 ZT1にレコードが存在しない場合、where句は明らかにfalseと評価します。健全性のためにAND句を括弧で囲み、何らかのOR句を追加します(@TTBLにSaleDateという名前のフィールドがあり、レコードをフェッチするだけであると想定しましたSaleDateが何らかの方法でその範囲内にある場合)、この問題が解消されることを期待できます。

SELECT Employee = COALESCE(ZT1.Employee,Z.Name), COUNT(ZT1.sales) AS Salecount, SUM(ISNULL(ZT1.[SaleTotal],0)) AS SaleTotal, SUM(ISNULL(ZT1.[SaleTotal],0) - ISNULL(ZT1.[TotalB4Discount],0)/NULLIF(ZT1.[SaleTotal],0)) AS ActualSale, SUM(ISNULL(ZT1.[SaleTotal],0) - ISNULL(ZT1.[TotalB4Discount],0)) AS ProfitMargin, ISNULL(Z.SaleTotal0,0) AS SaleTotal0, ISNULL(Z.SaleTotal1,0) AS SaleTotal1 FROM dbo.holdings AS ZT1 FULL OUTER JOIN @TTBL AS Z ON Z.Name = ZT1.Employee WHERE (ZT1.[SaleDate] >= '20170601' AND ZT1.[SaleDate] <= '20170625') OR (Z.[SaleDate] >= '20170601' AND Z.[SaleDate] <= '20170625') GROUP BY ZT1.Employee,Z.SaleTotal0,Z.SaleTotal1,Z.Name

3
Dan Truitt