选择具有日期时间的最新记录,如果不存在,请选择一些默认值

时间:2009-11-30 09:01:08

标签: sql-server

这是我的查询

SELECT lbi.ItemGrpId,igm.ItemGrpName,lbi.Qty,
'BidAmt' = CASE 
 WHEN lbi.ItemGrpId IN
 (
  SELECT DISTINCT vbd.ItemGrpId
  FROM tbVebdorBidDetails vbd
  WHERE vbd.BidID=139 AND vbd.VendorEmailID='satputeamit@gmail.com'
  AND vbd.UpdatedDateTime IN 
  (
   SELECT MAX(UpdatedDateTime) AS [MAXMIN] 
   FROM tbVebdorBidDetails WHERE BidID=139
   AND VendorEmailID='satputeamit@gmail.com'
   GROUP BY ItemGrpID
  )
 )
 THEN
  MIN(cast(cast(vbd.BidAmt as decimal) / cast (vbd.CurrencyExchangeRate as decimal) as decimal(18,2))) 
 ELSE
  0.0  
 END
FROM tbLnkBidItemGrp lbi   
INNER JOIN tbVebdorBidDetails vbd ON lbi.BidID=vbd.BidID
INNER JOIN    
(    
 SELECT ItemGrpId,
 MAX(UpdatedDateTime) AS [MAXMIN] 
 FROM tbVebdorBidDetails WHERE BidID=139
 AND VendorEmailID='satputeamit@gmail.com'
 GROUP BY ItemGrpID   
) t2     
ON vbd.ItemGrpId=t2.ItemGrpId 
AND vbd.UpdatedDateTime= t2.[MAXMIN] 
INNER JOIN tbItemGrpMaster igm ON igm.ItemGrpId=lbi.ItemGrpID    
WHERE vbd.BidID=139 AND vbd.VendorEmailID='satputeamit@gmail.com'
GROUP BY lbi.ItemGrpId,vbd.BidAmt,igm.ItemGrpName,lbi.Qty

我想为每个不同的ItemGrpId选择BidAmt 但是在这里它用每个ItemGrpId重复BidAmt

结果是这样的

ItemGrpId    ItemGrpName    Qty       BidAmt 
70           Screw          700       12
70           Screw          700       16
80           NutBolt        1000      12
80           NutBolt        1000      16

我应该

ItemGrpId    ItemGrpName    Qty       BidAmt 
70           Screw          700       12
80           NutBolt        1000      16

1 个答案:

答案 0 :(得分:0)

您在tbVebdorBidDetails和tbLnkBidItemGrp之间的联接仅使用BidId,而显然每个出价可以包含多个ItemGrpId值。所以你在这个连接中得到了多行。为了确保在tbVebdorBidDetails表中没有匹配项时得到结果,您需要使用LEFT JOIN,这可确保最终结果集包含连接中最左侧表中的一行,即使最右侧没有匹配项也是如此。表。 (最右边的表中的连接列将填充NULL)。

无论如何,您可能希望将联接更改为:

FROM tbLnkBidItemGrp lbi   
    INNER JOIN tbItemGrpMaster igm ON igm.ItemGrpId=lbi.ItemGrpID  
    LEFT JOIN tbVebdorBidDetails vbd ON lbi.BidID=vbd.BidID
               AND lbi.ItemGrpId = vbd.ItemGrpID

请注意(就像我在上面的代码段中所示)我将tbItemGrpMaster上的INNER JOIN移到了查询的前面,这样即使tbItemGrpMaster表中没有匹配项,它仍会执行。您可能需要进行更多更改才能使查询正常工作 - 我现在不在我的办公桌旁,因此无法测试更改。

顺便说一句,你的查询比它需要的要复杂得多,效率低得多。这是一种简化它的可能方法(假设您在SQL 2005上运行,因此可以使用ROW_NUMBER()) - 您可以简单地选出每个组中的第一行,按日期降序排序:

SELECT ItemGrpId, 
 (SELECT ItemGrpName FROM tbItemGrpMaster igm WHERE igm.ItemGrpId=vbd.ItemGrpID) as ItemGrpName,
 Qty, 
 BidAmt
FROM (
 SELECT lbi.ItemGrpId,
  lbi.Qty,
  ISNULL (cast(cast(vbd.BidAmt as decimal) / cast (vbd.CurrencyExchangeRate as decimal) as decimal(18,2)), 0.0) as BidAmt,
  ROW_NUMBER() OVER (PARTITION BY lbi.ItemGrpId ORDER BY UpdatedDateTime DESC) as RowNum
 FROM tbLnkBidItemGrp lbi   
  LEFT JOIN tbVebdorBidDetails vbd ON lbi.BidID=vbd.BidID AND lbi.ItemGrpId = vbd.ItemGrpID
 WHERE vbd.BidID=139 AND vbd.VendorEmailID='satputeamit@gmail.com'
) vbd
WHERE RowNum = 1;

BTW,这是我正在使用的架构:

IF EXISTS(SELECT name FROM sysobjects WHERE name = N'tbVebdorBidDetails' AND xtype='U')
 DROP TABLE tbVebdorBidDetails;
CREATE TABLE tbVebdorBidDetails
(
 BidID int,
 VendorEmailID varchar(100),
 UpdatedDateTime datetime,
 ItemGrpID int,
 BidAmt decimal,
 CurrencyExchangeRate decimal
);

INSERT INTO tbVebdorBidDetails (BidId, VendorEmailId, UpdatedDateTime, ItemGrpId, BidAmt, CurrencyExchangeRate)
 VALUES (139, 'satputeamit@gmail.com', '1/1/2009', 1, 100, 1);
INSERT INTO tbVebdorBidDetails (BidId, VendorEmailId, UpdatedDateTime, ItemGrpId, BidAmt, CurrencyExchangeRate)
 VALUES (139, 'satputeamit@gmail.com', '2/1/2009', 1, 200, 1);
INSERT INTO tbVebdorBidDetails (BidId, VendorEmailId, UpdatedDateTime, ItemGrpId, BidAmt, CurrencyExchangeRate)
 VALUES (139, 'satputeamit@gmail.com', '3/1/2009', 1, 300, 1);
INSERT INTO tbVebdorBidDetails (BidId, VendorEmailId, UpdatedDateTime, ItemGrpId, BidAmt, CurrencyExchangeRate)
 VALUES (139, 'satputeamit@gmail.com', '1/1/2009', 2, 1000, 1);
INSERT INTO tbVebdorBidDetails (BidId, VendorEmailId, UpdatedDateTime, ItemGrpId, BidAmt, CurrencyExchangeRate)
 VALUES (139, 'satputeamit@gmail.com', '2/1/2009', 2, 2000, 1);
INSERT INTO tbVebdorBidDetails (BidId, VendorEmailId, UpdatedDateTime, ItemGrpId, BidAmt, CurrencyExchangeRate)
 VALUES (139, 'satputeamit@gmail.com', '3/1/2009', 2, 3000, 1);

IF EXISTS(SELECT name FROM sysobjects WHERE name = N'tbLnkBidItemGrp' AND xtype='U')
 DROP TABLE tbLnkBidItemGrp;
CREATE TABLE tbLnkBidItemGrp
(
 BidId int,
 ItemGrpId int,
 Qty int
);
INSERT INTO tbLnkBidItemGrp (BidId, ItemGrpId, Qty) VALUES (139, 1, 100)
INSERT INTO tbLnkBidItemGrp (BidId, ItemGrpId, Qty) VALUES (139, 2, 200)

IF EXISTS(SELECT name FROM sysobjects WHERE name = N'tbItemGrpMaster' AND xtype='U')
 DROP TABLE tbItemGrpMaster;
CREATE TABLE tbItemGrpMaster
(
 ItemGrpId int,
 ItemGrpName varchar(100)
);
INSERT INTO tbItemGrpMaster (ItemGrpId, ItemGrpName) VALUES (1, 'Screw')
INSERT INTO tbItemGrpMaster (ItemGrpId, ItemGrpName) VALUES (2, 'NutBolt')