2017-05-08 33 views
1

customersテーブルには、2016年度に1500件の注文があった1000人の顧客がいますが、FYにはすべての顧客を合計注文数で表示します顧客がそのFYに注文をしたかどうかを判断する。しかし、SQL Server 2012の次のクエリは1490のみを表示しています。LEFT OUTER JOINに左からの主キーが含まれていない理由

ここでは表示されないことがありますか?

SELECT c.CustomerID, count(*) AS TotalOrders 
FROM Customers c 
LEFT JOIN Orders o ON c.CustomerID = o.CustomerID 
WHERE o.FiscalYear = '2016' 
GROUP BY c.CustomerID 

UPDATE

次のクエリでは、唯一の1以上のレコード(1491)を返します - まだ9つの以上のレコードが欠落します。

SELECT c.CustomerID, count(*) AS TotalOrders 
FROM Customers c 
LEFT JOIN Orders o ON c.CustomerID = o.CustomerID 
        AND o.FiscalYear = '2016' 
GROUP BY c.CustomerID 
+1

where句は、結合後に適用されます。したがって、結合は、注文なしで顧客のnull値を戻しています。それらの顧客は注文はありませんので、FY2016と等しくないので、レコードは除外されています。外部ジョインに関わる制限基準をジョイン基準に移動して、ジョインに加えて制限を課すように修正します。 – xQbert

+3

合計レコード数は1000(顧客)でなければなりません。合計の数は1500にする必要があります。合計が1500未満になる可能性のある唯一の差異は、顧客と孤立した注文を削除したことです。または1500の2016の注文のあなたのカウントは最初から間違っています。 (顧客から得意先コードを選択していない)顧客IDとFiscalYear = '2016'のレコードからいくつかのレコードを選択した注文からSELECT *を実行しますか? – xQbert

+0

ええ、私は次のようなものをチェックし始めます:あなたのFiscalYearは、実際にはすべてのレコードの "2016"と区別できますか?タイプミスの可能性はありますか?レコードはどのように削除されていますか(bit/intフラグ)? –

答えて

6

あなたwhere句はInner joinleft outer joinを回しています。 AND

変更を:

SELECT c.CustomerID, count(o.CustomerID) AS TotalOrders 
FROM Customers c 
LEFT JOIN Orders o 
    ON c.CustomerID = o.CustomerID 
    AND o.FiscalYear = '2016'  -- Here 
GROUP BY c.CustomerID 
+0

「LEFT JOIN」に「Where」条件を含めようとしましたが、合計レコードが1だけ増えたと言いました。 – nam

+0

@namこれはクエリではありません。今すぐCustomersテーブルにいくつの個別CustomerIDがあるか確認できますか? – GurV

+2

問い合わせに間違いがあります。注文をしていない顧客に対しては、0をカウントするために 'COUNT(*)'は 'COUNT(o.CustomerID) 'などでなければなりません。 –

0

正しいSQLは次のとおりです。

SELECT c.CustomerID, count(o.CustomerID) AS TotalOrders, 
     sum(count(o.CustomerID)) over() as TotalTotalOrders 
FROM Customers c LEFT JOIN 
    Orders o 
    ON c.CustomerID = o.CustomerID AND o.FiscalYear = '2016' 
GROUP BY c.CustomerID; 

TotalTotalOrdersは、すべての注文(または有効な顧客IDを有する少なくとももの)でなければなりません。

0

注文があったかどうかにかかわらず、注文番号を問わず、すべての顧客を一覧表示します。sumは、2016年に配置されたすべての注文を数え、残りは無視してインテンジャーを返します(つまり、nullになることはありません)。

SELECT 
    c.CustomerID 
    ,sum(case when o.FiscalYear = '2016' then 1 else 0 end) AS TotalOrders 
FROM Customers c 
LEFT JOIN Orders o 
ON c.CustomerID = o.CustomerID 
GROUP BY c.CustomerID 
+0

ええと、@ Gurwinderの答えと同様に動作しませんが、要件が変わると柔軟性が増します。 –

関連する問題