【问题标题】:Query returning NULL values when multiple joins are performed to compare two tables执行多个连接以比较两个表时查询返回 NULL 值
【发布时间】:2014-08-12 13:56:46
【问题描述】:

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

我在SQL Fiddle 上拥有一切

但由于某些原因,它在 BID 和 OFFER 列中返回空值,这不应该 在上面两个表上运行 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 的行,所以 出价最高、出价最低的行是 回来。对于 Product abc 和 term Q4 14/Q1 15 也是如此。但是对于 比较时,第一个表中的产品 abc 和术语 Sep14/Oct14 与第二个表相同的产品和术语,第二个表有 更好的出价和报价值,因此该行不会在 结果

有更好的方法吗?

【问题讨论】:

  • 将 MAX(Bid) 和 MIN(Offer) 再次加入没有记录匹配的 InferredBids 时出错。

标签: sql sql-server


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    好的,我不明白你想用这个实现什么,但我可以看到一些问题:

    • 您正在整理每个“事物”的最高出价/最低出价,然后将它们加入到原始表格中。但这将不起作用,除非单行具有最高出价和最低出价;
    • 您关于何时显示出价/出价的一些逻辑意味着您将在输出中包含 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 2014-10-12
      • 1970-01-01
      相关资源
      最近更新 更多