帮助复杂的SELECT查询

时间:2011-05-14 15:18:06

标签: sql sql-server 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 Users.ID=@UserID 
GROUP BY Users.Balance, Users.FreeBids, Auctions.ID

我的问题是,如果在Bids表上找不到UserID,它将不返回任何行。

我知道这与我的

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

但即使用户在Bids表上没有,我也不知道如何让它返回。

3 个答案:

答案 0 :(得分:3)

您正在进行INNER JOIN,只有在连接两侧都有结果时才返回行。要获得所需内容,请更改WHERE子句,如下所示:

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

您可能还需要更改SELECT语句以处理Bids.Burned为NULL。

如果您想要返回行,即使没有匹配的竞价,那么您将不得不对您的查询进行更深层次的更改。

答案 1 :(得分:1)

  

我的问题是,如果在Bids表上找不到UserID,它将不返回任何行。

然后INNER JOIN Bids/Auctions应该留下外连接。您编写它的方式是,您过滤用户,以便只显示出价和拍卖中的用户。

答案 2 :(得分: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(公用表表达式),基本上是一种制作一次性使用视图的方法,也是构建查询的好方法。