2011-05-14 60 views
0

我有這樣的SELECT查詢:幫助併發SELECT查詢

SELECT Auctions.ID, Users.Balance, Users.FreeBids, 
     COUNT(CASE WHEN Bids.Burned=0 AND Auctions.Closed=0 THEN 1 END) AS 'ActiveBids', 
     COUNT(CASE WHEN Bids.Burned=1 AND Auctions.Closed=0 THEN 1 END) AS 'BurnedBids' 
FROM (Users INNER JOIN Bids ON Users.ID=Bids.BidderID) 
    INNER JOIN Auctions 
    ON Bids.AuctionID=Auctions.ID 
WHERE [email protected] 
GROUP BY Users.Balance, Users.FreeBids, Auctions.ID 

我problam是,它不返回行,如果用戶名不能在投標表中找到。

我知道它的東西,與我

(Users INNER JOIN Bids ON Users.ID=Bids.BidderID) 

做的,但我不知道如何使它返回即使用戶沒有在投標表。

回答

3

你正在做一個INNER JOIN,它只在連接兩邊都有結果時才返回行。爲了得到你想要的東西,改變你的WHERE子句這樣的:

Users LEFT JOIN Bids ON Users.ID=Bids.BidderID 

你也可能不得不改變你的SELECT語句來處理Bids.Burned爲NULL。

如果您想要返回行,即使沒有匹配的拍賣,那麼您必須對查詢進行一些更深入的更改。

1

我的問題是,如果用戶ID無法在投標表中找到,它將不返回任何行。

然後INNER JOIN Bids/Auctions可能應該留下外連接。您編寫它的方式,是對用戶進行過濾,以便僅出價和出價中的用戶出現。

0

左連接是一個簡單的答案,但如果您擔心性能問題,我會考慮重新寫一點。首先,組中的列按順序排列(儘管它通常不會改變結果)。一般來說,您想要按照首先編制索引的列進行分組。

此外,有可能重新編寫此查詢只有一個羣組,這可能會加快速度。

嘗試了這一點:

with UserBids as (
    select 
     a.ID 
    , b.BidderID 
    , ActiveBids = count(case when b.Burned = 0 then 1 end) 
    , BurnedBids = count(case when b.Burned = 0 then 1 end) 
    from Bids b 
    join Auctions a 
     on a.ID = b.AuctionID 
    where a.Closed = 0 
    group by b.BidderID, a.AuctionID 
) 

select 
    b.ID 
, u.Balance 
, u.FreeBids 
, b.ActiveBids 
, b.BurnedBids 
from Users u 
left join UserBids b 
    on b.BidderID = u.ID 
where u.ID = @UserID; 

如果你不熟悉的with UserBids as...,它被稱爲CTE(公共表表達式),基本上是一種方法,使一個一次性使用的視圖,一個很好的方式來構建你的查詢。