使用SQL连接检索列中每个不同值的数据集

时间:2014-12-10 15:36:51

标签: sql-server join

我正在从SQL Server上的两个SQL表中检索数据,我试图从右表中获取左表中列中每个不同值的所有行,无论是否匹配

例如,我有两个名为products的表,以及以下数据的交易

产品表

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-02-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 
         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')

我得到了以下结果

 Delivery     Product    Trades  BBLperDay   M3  WeightedAverage
 January 2015   ABC         1   0.5072      2500      -3.25
 February 2015  ABC         1   0.5616      2500      -3.4
 January 2015   PQR         2   1.0145      5000        -7
 (null)         XYZ         0   (null)      (null)      (null)

以上结果可用于查询,但我正在尝试获取结果,以便从上面的结果中我希望Products table中的所有行都为Delivery值提供Delivery value 1}}默认为每个等效结果,其他字段为NULL,如下所示

 Delivery     Product    Trades  BBLperDay   M3  WeightedAverage
  January 2015   ABC        1   0.5072      2500      -3.25
  January 2015   PQR        2   1.0145      5000        -7
  January 2015   XYZ        0   (null)      (null)      (null)
  February 2015  ABC        1   0.5616      2500      -3.4
  February 2015  XYZ        0   (null)      (null)      (null)
  February 2015  PQR        0   (null)      (null)      (null)

以上结果可以从我2015年1月交付的产品ABC和PQR但产品表作为2015年1月缺少的另外一个产品XYZ的实际结果来解释,因此我在2015年1月添加了XYZ,交付时间为1月2015年仍为NULL。 2015年2月发货的情况也是如此,它只有ABC,所以我在产品中添加了产品XYZ和PQR。

请参阅http://sqlfiddle.com/#!6/db1508/3

May I know a good way to get this data?

1 个答案:

答案 0 :(得分:1)

我首先要构建交付产品的“主干”,并使用左连接将原始查询放在其上。这里显示的是CTE。

WITH deliveryProducts AS
(
     SELECT DISTINCT FORMAT(a.Delivery,'MMMM yyyy') AS Delivery, b.Product 
     FROM DEALS as a, PRODUCTS as b Where CAST(a.TradeDate as date)='2014-12-08'
)
, deliveryActuals AS
(
     SELECT
           FORMAT(a.Delivery,'MMMM yyyy') AS Delivery,

           b.Product,ISNULL(COUNT(a.Id),0) 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')
)

SELECT
     dp.Delivery, dp.Product, trades, BBLperDay, M3, WeightedAverage
FROM
     deliveryProducts dp

LEFT JOIN deliveryActuals da
     on dp.Delivery = da.Delivery
     and dp.product = da.Product

ORDER BY dp.Delivery

此处位于您的SQLFiddle