简体   繁体   English

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

[英]Using SQL join to retrieve set of data for each different value in a column

I am working on retrieving data from two SQL tables on SQL Server in which I am trying to get all rows from right table for each distinct value in a column in left table no matter if there is a match or not 我正在从SQL Server的两个SQL表中检索数据,在其中我试图从右表中获取左表中列中每个不同值的所有行,无论是否存在匹配项

For example I have two tables named products and Deals with following data 例如,我有两个名为products的表,并处理以下数据

Products table 产品表

Id Product
1  ABC
2  XYZ
3  PQR

Deals Table 交易表

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 

I applied following query to the above tables 我对以下表格应用了以下查询

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

And I got following results 我得到了以下结果

 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)

The above results are expected for the query but I am trying a way to get the results such that from the above results I want all rows in Products table for each distinct Delivery value by making Delivery value as default for every equivalent result and other fields be NULL as follows 以上结果是查询的预期结果,但我正在尝试一种获取结果的方法,以便通过使每个等效结果和其他字段的默认Delivery value Delivery ,从上述结果中,使Products table中的每个行具有每个不同的Delivery值。 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)

The above results can be explained as from actual results I have January 2015 Delivery for products ABC and PQR but the Products table as one more product XYZ which is missing for January 2015, so I added XYZ for January 2015 with Delivery as January 2015 and remaining NULL. 以上结果可以从实际结果中得到解释,我有2015年1月交付的产品ABC和PQR,但Products表又是另外一个产品XYZ,2015年1月缺失了,所以我添加了XYZ于2015年1月,交付为2015年1月,其余空值。 Same is the case with February 2015 Delivery it has only ABC so I added products XYZ and PQR to the results. 与2015年2月交货的情况相同,它只有ABC,因此我在结果中添加了产品XYZ和PQR。

Please refer to http://sqlfiddle.com/#!6/db1508/3 请参考http://sqlfiddle.com/#!6/db1508/3

May I know a good way to get this data?

I'd just build out that 'backbone' of delivery products first and put your original query against it with a left join. 我只是先构建交付产品的“主干”,然后用左联接将您的原始查询针对它。 Shown here with CTEs. 与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

Here it is in your SQLFiddle 它在您的SQLFiddle中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM