检索右表中的所有行以及使用右连接匹配左表中的行的结果不正确

时间:2014-12-10 14:27:22

标签: sql-server join

我正在检索两个SQL tables on SQL Server中的数据,其中我试图从右表中获取所有行以及左表中的匹配行并使其他列为null

例如,我有两个名为productsDeals的表,其中包含以下数据

产品表

Id Product
1  ABC
2  XYZ
3  PQR

促销表

Id  TradeDate  Product Volume   Price    Delivery
56  2014-12-08  ABC     2500    -3.25   2015-01-01 
57  2014-12-08  ABC     2500    -3.4    2015-01-01 
63  2014-12-08  PQR     2500    -7      2015-01-01 
64  2014-12-08  PQR     2500    -7      2015-01-01 

我将以下查询应用于上表

SELECT
         FORMAT(a.Delivery,'MMMM yyyy') AS Delivery,

         b.Product,COUNT(a.Id) AS Trades, 
         ROUND(((6.2898*SUM(a.Volume ))/DAY(EOMONTH(DATEADD(MONTH, DATEDIFF(MONTH, 0,a.Delivery), 0))))*0.001,4) AS BBLperDay,
         SUM(a.Volume) AS M3,       
         ROUND(SUM(a.Volume*a.Price)/Sum(a.Volume),4) AS WeightedAverage
FROM     Deals AS a right outer join Products AS b ON a.Product=b.Product
WHERE    CAST(a.TradeDate as date)='2014-12-08' 
GROUP BY b.Product,CAST(a.TradeDate as date), 
         DATEADD(MONTH, DATEDIFF(MONTH, 0,a.Delivery),0),  FORMAT(a.Delivery,'MMMM yyyy')

我得到了以下结果

Delivery     Product    Trades  BBLperDay   M3  WeightedAverage
January 2015    ABC        2    1.0145  5000     -3.325
January 2015    PQR        2    1.0145  5000      -7

但是我希望包含products表中的所有条目,其他字段保持为NULL,如下所示

Delivery      Product   Trades  BBLperDay   M3  WeightedAverage
January 2015    ABC        2    1.0145      5000     -3.325
NULL            XYZ      NULL   NULL        NULL     NULL
January 2015    PQR        2    1.0145      5000      -7

从上面的结果中可以看出,即使产品XYZ也包含在其中,这就是我想要的

SQL FIDDLE:http://sqlfiddle.com/#!6/4db19/2 我有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

您可以尝试将日期条件移动到ON子句,因为这样可以通过WHERE子句消除应该与右连接一起出现的行。

SELECT
         FORMAT(a.Delivery,'MMMM yyyy') AS Delivery,

         b.Product,COUNT(a.Id) AS Trades, 
         ROUND(((6.2898*SUM(a.Volume ))/DAY(EOMONTH(DATEADD(MONTH, DATEDIFF(MONTH, 0,a.Delivery), 0))))*0.001,4) AS BBLperDay,
         SUM(a.Volume) AS M3,       
         ROUND(SUM(a.Volume*a.Price)/Sum(a.Volume),4) AS WeightedAverage
FROM     Deals AS a right outer join Products AS b 
         ON a.Product=b.Product 
         AND CAST(a.TradeDate as date)='2014-12-08' 
GROUP BY b.Product,CAST(a.TradeDate as date), 
         DATEADD(MONTH, DATEDIFF(MONTH, 0,a.Delivery),0),  FORMAT(a.Delivery,'MMMM yyyy')

答案 1 :(得分:0)

问题在于您的WHERE子句,它排除了记录不存在的结果。试试这个:

SELECT
         FORMAT(a.Delivery,'MMMM yyyy') AS Delivery,

         b.Product,COUNT(a.Id) AS Trades, 
         ROUND(((6.2898*SUM(a.Volume ))/DAY(EOMONTH(DATEADD(MONTH, DATEDIFF(MONTH, 0,a.Delivery), 0))))*0.001,4) AS BBLperDay,
         SUM(a.Volume) AS M3,       
         ROUND(SUM(a.Volume*a.Price)/Sum(a.Volume),4) AS WeightedAverage
FROM     Deals AS a right outer join Products AS b ON a.Product=b.Product
WHERE    CAST(a.TradeDate as date)='2014-12-08' OR a.TradeDate IS NULL
GROUP BY b.Product,CAST(a.TradeDate as date), 
         DATEADD(MONTH, DATEDIFF(MONTH, 0,a.Delivery),0),  FORMAT(a.Delivery,'MMMM yyyy')

OR a.TradeDate IS NULL子句中添加WHERE