从SQL表中的两个不同行中查找最少两列

时间:2014-06-04 15:20:57

标签: sql sql-server sql-view

我正在研究一个SQL视图,它返回两列的差异以及属于两个不同的单个表行的两列的最小值。

我能够找到差异,但无法返回两列的最小值

我有下表

 id      Market  Grade       Term    BidVolume   Bid     Offer   OfferVolume
    1       Heavy   ABC         Jun14 1000     -19.5      -17         2500
    2       Heavy   ABC         Jul14 2000      -20      -17.5        1400 
    3       Sour    XYZ         Jun14 3000      -30       -17         2300  
    4       Sour    XYZ         Jul14 1500      -32       -27         2900

我有以下SQL查询及其结果

CREATE VIEW [dbo].[InferredBids] AS
WITH numbered AS
  ( SELECT id, product, grade, term, bid, offer, termid, bidVolume, offerVolume,
           row_number() OVER (Partition BY Product, Grade ORDER BY termid) i
   FROM dbo.CanadianCrudes) --select * from numbered
SELECT r1.id AS Id,
       r1.product + '/' + r1.grade AS Market,
       r1.term + '/' + r2.term AS Term,
       r1.Bid - r2.Offer [Bid], r1.Offer - r2.Bid [Offer]
FROM numbered r1
JOIN numbered r2 ON r1.product = r2.product
AND r1.grade = r2.grade
AND r1.termid+1=r2.termid
AND r1.i<r2.i
AND r1.term!=r2.term

以上查询的结果如下

Market     Term          Bid                   Offer
Heavy/ABC  Jun14/Jul14   (-19.5-(-17.5))=-2    (-17-(-20))=3
Sour/XYZ  Jun14/Jul14    (-30-(-27))=-3        (-17-(-32))=15

但我试图包含另外两个名为BidVolume和OfferVolume的列,结果应该类似于

Market     Term          BidVolume                  Bid                   Offer        OfferVolume     
 Heavy/ABC  Jun14/Jul14  Min(1000,1400)=1000    (-19.5-(-17.5))=-2     (-17-(-20))=3  Min(2500,2000)=2000
 Sour/XYZ  Jun14/Jul14    Min(3000,2900)=2900   (-30-(-27))=-3        (-17-(-32))=15   Min(2300,1500)=1500

包含它们的最佳方式是什么

2 个答案:

答案 0 :(得分:4)

聚合函数(例如MIN)用于聚合多行,并且不会按照您的预期执行(正如您已经发现的那样)。相反,您应该使用case来选择要显示的表和列。 是的,我的意思是&#34; table&#34;这是因为您的两个连接行来自不同的逻辑表,别名为t1t2

例如,对于BidVolume

case when r1.BidVolume < r2.OfferVolume then r1.BidVolume else r2.OfferVolume end

答案 1 :(得分:0)

抱歉 - 我误解了这个问题。

真正的答案是你收到的第一个答案很接近。问题是它只比较4个值中的2个。

在你的SQL中,你总是在2条记录中比较2列 - 你需要至少4个不同的值,所以在mysql中你会这样做:

least( r1.bidVolume, r1.offerVolume, r2.bidVolume, r2.offerVolume) as Minimum_Volume

这是我对后代的原始回答 要获得两个不同列的最小聚合,您需要 a)从给定行的两列中获得最小值的表达式 b)汇总所有行的上述表达式的最小值

对于a),我将使用mysql“IF”语法,你可以调整到你选择的sql。以下查询将从您在每个市场和每个等级基础上发布的第一个表中选择出价和要约量之间的最小值:

select Market, Grade, min( if( BidVolume < OfferVolume, BidVolume, OfferVolume)) MinVol
from YourTable
group by Market, Grade
;

如果您将上述内容用作模板,则可以根据需要调整其他业务规则。

上述结果将是:

Market  Grade       MinVol   
Heavy   ABC         1000
Sour    XYZ         1500