1

我正在使用 MS SQL。我有两张桌子:

1) “OrderProducts” - 此表存储订单中的所有产品。还有另一个 Orders 主表,我们可以从这张图中省略。Orders 主表存储订单的主要数据,而 OrderProducts 表存储详细信息。

2) “TransactionFeeProducts” - 此表存储我要为订单收取的所有产品的交易费用。它有一个 BatchID,其中多个产品可以有相同的 BatchID。

基本上,所有 OrderDate 介于 TransactionFeeProducts.FromDate 和 TransactionFeeProducts.ToDate 之间的订购产品,都将收取 TransactionFeeProducts.TransactionFee

订购产品

  • 产品编号
  • 数量
  • 订购日期

交易费用产品

  • 批号
  • 产品编号
  • 从日期
  • 迄今为止
  • 手续费

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 返回 TransactionFeeProducts 中 BatchID = 3 的所有记录。 SUM(Quantity) 应该只给我在 TransactionFeeProducts.FromDate 和 TransactionFeeProducts.ToDate 之间进行 OrderDate 的总和

如果 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子句中,它将影响查询过滤,就像您使用 an 一样INNER JOIN,说明您将只包含来自TransactionFeeProductswhere的条目OrderDate >= 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

另一方面,选择 2 说:

仅返回 T1 中的所有行,仅返回 T2 中的t1.ID = t2.ID行,然后在此之后,仅取行 wheret2.DateValue BETWEEN t1.FromDate AND t1.ToDate

SQL SERVER – JOIN 简介 – JOIN的基本知识总是很方便。

于 2012-08-28T04:40:32.073 回答
1

我更喜欢 astander 的方法(在 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 回答