我正在使用MS SQL。我有两张桌子:
1)“OrderProducts” - 此表存储订单的所有产品。还有另一个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不会返回任何记录。
请帮忙。非常感谢你。
答案 0 :(得分:6)
将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
一样,说明您只包含来自TransactionFeeProducts
其中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中的所有行,仅返回来自t1.ID = t2.ID AND t2.DateValue BETWEEN t1.FromDate AND t1.ToDate
另一方面选择2说:
返回T1中的所有行,只返回来自T2 t1.ID = t2.ID
的所有行,然后返回t2.DateValue BETWEEN t1.FromDate AND t1.ToDate
答案 1 :(得分:0)
我更喜欢astander的方法(在JOIN中过滤),但有时候有用的替代方法是在加入字段上添加一个OR IS NULL,例如。
WHERE
TransactionFeeProducts.BatchID = 3
AND
(OrderProducts.ProductID IS NULL
OR
(
OrderDate >= TransactionFeeProducts.FromDate AND
OrderDate <= TransactionFeeProducts.ToDate
))