Выбор последней записи с указанием даты и времени и, если она не существует, выберите значение по умолчанию - PullRequest
0 голосов
/ 30 ноября 2009

Это мой запрос

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

Я хочу выбрать BidAmt для каждого отдельного ItemGrpId Но здесь он повторяет BidAmt с каждым ItemGrpId

Результат примерно такой

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 голосов
/ 30 ноября 2009

Ваше объединение между 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

Обратите внимание, что (как я показал во фрагменте выше) я переместил ваш INNER JOIN в tbItemGrpMaster на более ранний в запросе, чтобы он все равно выполнялся, даже если в таблице 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;

Кстати, вот схема, которую я использовал:

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')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...