执行多个连接以比较两个表时,查询返回NULL值

时间:2014-08-12 13:56:46

标签: sql sql-server

我正在处理一个比较两个表的查询,如果它在第一个表中,则返回最佳值。

我拥有SQL Fiddle

上的所有内容

但由于某些原因,它在BID和OFFER列中返回空值,而不应该返回 pon在上面两个表上运行SQL查询,结果应该像

╔════╦════════╦═════════════╦═══════╦══════╦═══════╦═════════╗
║ Id ║ Market ║    Term     ║ BidCP ║ Bid  ║ Offer ║ OfferCP ║
╠════╬════════╬═════════════╬═══════╬══════╬═══════╬═════════╣
║ 14 ║ abc    ║ Q4 14/Q1 15 ║ begrt ║ -425 ║ NULL  ║ vf      ║
║  1 ║ C1     ║ Sep14/Oct14 ║ punt  ║  -50 ║ NULL  ║ vgc     ║
╚════╩════════╩═════════════╩═══════╩══════╩═══════╩═════════╝

以上结果可以解释为:

  

对于第一个表中的Product C1,没有带有Sep14/Oct14项的行   具有最高出价值然后最低出价值的行是   回。同样对于产品abc和术语Q4 14 / Q1 15.但是对于   比较时第一个表中的产品abc和术语Sep14/Oct14   与第二个表相同的产品和术语,第二个表有   因此,更好的出价和报价值,该行不会返回   结果

有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

在我看来,您的查询和语法会被>,<,MAX()MIN()函数混淆。据我所知,你正在处理负数,并期望最大的绝对价值:所以-500比-400更大。然而,告诉SQL处理MAX和MIN正在寻找列的实际值,并且在数学术语中-400大于-500。

尝试将MAX()替换为MIN(),反之亦然。或者,尝试使用ABS()函数获取数据的绝对值(例如MAX(ABS(Bid))

答案 1 :(得分:0)

好吧,我不明白你想要实现的目标,但我可以看到很多问题:

  • 您正在为每个“事物”整理最高出价/最低出价,然后将这些出价连接回原始表格。但是,除非单行具有最高出价和最低要约,否则这将无效;
  • 您何时显示出价/优惠的一些逻辑意味着您将在输出中包含NULL,因此您应该看到它们;
  • 您使用负值(和负NULL !!)时,您的值之间的比较似乎很混乱。

我把它扔进了一个稍微修改过的查询版本中,可以帮助你找出出错的地方?

DECLARE @InferredBids TABLE (Market VARCHAR(10), Term VARCHAR(20), BidCP VARCHAR(10), Bid FLOAT, Offer FLOAT, OfferCP VARCHAR(10));
INSERT INTO @InferredBids VALUES('C1', 'Sep14/Oct14', 'Nothing', -60, -40, '');
INSERT INTO @InferredBids VALUES('C1', 'Sep14/Oct14', 'punt', -50, NULL, 'vgc');
INSERT INTO @InferredBids VALUES('abc', 'Sep14/Oct14', 'disc', -390, -285, 'fvfvf');
INSERT INTO @InferredBids VALUES('abc', 'Sep14/Oct14', 'vgc', -415, -185, 'vfvfv');
INSERT INTO @InferredBids VALUES('abc', 'Q4 14/Q1 15', 'begrt', -425, NULL , 'vf');
DECLARE @CanadianCrudes TABLE (Product VARCHAR(10), Term VARCHAR(20), BidCP VARCHAR(10), Bid FLOAT, Offer FLOAT, OfferCP VARCHAR(10));
INSERT INTO @CanadianCrudes VALUES('C1','Sep14', 'dddddddd', -975, NULL,'xoom');
INSERT INTO @CanadianCrudes VALUES('C1','Sep14', 'efrt', -985, NULL, NULL);
INSERT INTO @CanadianCrudes VALUES('C1', 'Sep14', 'BPl', NULL, NULL, 'jjjj');
INSERT INTO @CanadianCrudes VALUES('abc', 'Sep14/Oct14', 'CVXvg', -350 , -300, 'Shl');

WITH t1 AS (
SELECT 
    Market,
    Term,
    MAX(Bid) AS MaxBid, 
    MIN(Offer) AS MinOffer           
FROM     
    @InferredBids 
GROUP BY 
    Market,
    Term),
t2 AS (
SELECT 
    Product,
    Term, 
    MAX(Bid) AS Bid, 
    MIN(Offer) AS Offer
FROM 
    @CanadianCrudes 
GROUP BY 
    Product,
    Term)
SELECT 
    t1.Market,
    t1.Term,
    ib.BidCP,
    ib.Bid AS InferredBid,
    cc.Bid AS CrudeBid,
    CASE WHEN ib.Bid >= ISNULL(cc.Bid, 0) THEN t1.MaxBid ELSE NULL END AS CalculatedBid,
    t1.MaxBid,
    ib.Offer AS InferredOffer,
    cc.Offer AS CrudeOffer,
    CASE WHEN ib.Offer <= ISNULL(cc.Offer, 0) THEN t1.MinOffer ELSE NULL END AS CalculatedOffer,
    ib.OfferCP
FROM
    t1 
    LEFT JOIN t2 ON t1.Market = t2.Product
    LEFT JOIN @InferredBids ib ON ib.Market = t1.Market AND ib.Term = t1.Term AND ib.Bid = t1.MaxBid --AND ib.offer = t1.minoffer
    LEFT JOIN @CanadianCrudes cc ON cc.Product = t2.Product AND cc.Term = t2.Term AND cc.Bid = t2.Bid; --AND cc.offer = t2.offer

如果你运行这个,你会得到这样的东西:

Market  Term        BidCP   InferredBid CrudeBid    CalculatedBid   MaxBid  InferredOffer   CrudeOffer  CalculatedOffer OfferCP
abc     Q4 14/Q1 15 begrt   -425        -350        NULL            -425    NULL            -300        NULL        vf
abc     Sep14/Oct14 disc    -390        -350        NULL            -390    -285            -300        NULL        fvfvf
C1      Sep14/Oct14 punt    -50         -975        -50             -50     NULL            NULL        NULL        vgc