1

MS SQL を使用しています。私は2つのテーブルを持っています:

1) "OrderProducts" - このテーブルには、注文に含まれるすべての製品が格納されます。Orders メイン テーブルがもう 1 つありますが、この図からは省略できます。Orders メイン テーブルには注文のメイン データが格納され、OrderProducts テーブルには詳細が格納されます。

2) "TransactionFeeProducts" - このテーブルには、注文に対して請求するすべての製品の取引手数料が格納されます。これには BatchID があり、複数の製品が同じ BatchID を持つことができます。

基本的に、OrderDate が TransactionFeeProducts.FromDate と TransactionFeeProducts.ToDate の間にあるすべての注文商品は、TransactionFeeProducts.TransactionFee が請求されます。

注文商品

  • 製品番号
  • 注文日

取引手数料商品

  • バッチID
  • 製品番号
  • 開始日
  • 現在まで
  • 取引手数料

SQL:

SELECT SUM(Quantity) as Orders, 
TransactionFeeProducts.ProductID, FromDate, ToDate 
FROM TransactionFeeProducts 
LEFT JOIN OrderProducts ON TransactionFeeProducts.ProductID = OrderProducts.ProductID
WHERE
OrderDate >= TransactionFeeProducts.FromDate AND 
OrderDate <= TransactionFeeProducts.ToDate AND 
TransactionFeeProducts.BatchID = 3
GROUP BY TransactionFeeProducts.ProductID, FromDate, ToDate 
ORDER BY SUM(Quantity) DESC

SQL で BatchID = 3 の TransactionFeeProducts のすべてのレコードを返すようにします。

SUM(Quantity) が 0 の場合、フィールドは NULL または 0 である必要があります。

私の問題は、SUM(Quantity) が 0 の場合、SQL がレコードを返さないことです。

助けてください。どうもありがとうございました。

4

2 に答える 2

8

JOIN条件を次のように変更します

SELECT  SUM(Quantity) as Orders,  
        TransactionFeeProducts.ProductID, 
        FromDate, 
        ToDate  
FROM    TransactionFeeProducts LEFT JOIN 
        OrderProducts   ON  TransactionFeeProducts.ProductID = OrderProducts.ProductID 
                        AND OrderDate >= TransactionFeeProducts.FromDate 
                        AND OrderDate <= TransactionFeeProducts.ToDate 
WHERE   TransactionFeeProducts.BatchID = 3 
GROUP BY    TransactionFeeProducts.ProductID, 
            FromDate, 
            ToDate  
ORDER BY    SUM(Quantity) DESC

違いは、句にフィルタリング条件を配置するWHEREと、 を使用する場合と同じようにクエリ フィルタリングに影響し、どこINNER JOINからのエントリのみを含めることを示すことです。TransactionFeeProductsOrderDate >= TransactionFeeProducts.FromDate and OrderDate <= TransactionFeeProducts.ToDate

次の例を見てください。

DECLARE @TABLE1 TABLE(
        ID INT,
        FromDate DATETIME,
        ToDate DATETIME
)

INSERT INTO @TABLE1 SELECT 1, '01 Jan 2012','31 Jan 2012'

DECLARE @TABLE2 TABLE(
        ID INT,
        DateValue DATETIME
)

INSERT INTO @TABLE2 SELECT 1, '01 Feb 2012'

SELECT  *
FROM    @TABLE1 t1 LEFT JOIN
        @TABLE2 t2  ON  t1.ID = t2.ID
                    AND t2.DateValue BETWEEN t1.FromDate AND t1.ToDate

SELECT  *
FROM    @TABLE1 t1 LEFT JOIN
        @TABLE2 t2 ON   t1.ID = t2.ID
WHERE   t2.DateValue BETWEEN t1.FromDate AND t1.ToDate

選択 1 は次のように述べています。

T1 のすべての行を返し、T2 の行のみを返します。t1.ID = t2.ID AND t2.DateValue BETWEEN t1.FromDate AND t1.ToDate

一方、Select 2 は次のように述べています。

T1 からすべての行を返し、T2 where からの行のみを返しt1.ID = t2.ID、その後、行のみを取得します wheret2.DateValue BETWEEN t1.FromDate AND t1.ToDate

SQL SERVER – JOIN の紹介 – JOIN の基本は常に手元にあると便利です。

于 2012-08-28T04:40:32.073 に答える
1

私は別のアプローチ(JOINでのフィルタリング)を好みますが、時には便利な代替手段は、結合フィールドに OR IS NULL を追加することです。

WHERE
 TransactionFeeProducts.BatchID = 3
 AND
(OrderProducts.ProductID IS NULL
 OR 
(
   OrderDate >= TransactionFeeProducts.FromDate AND 
   OrderDate <= TransactionFeeProducts.ToDate 

))
于 2012-08-28T05:24:40.913 に答える