2011-11-02 68 views
0

我有以下表格:SQL双外连接?

Users - Users of the site 
Matchups - Matchups between two teams 
Periods - The periods in which matchups take place 
MatchupResults - The results of the matchups 
UserPicks - The user's choice of who will win the matchup (5 picks for each period) 
Teams - Teams in the matchups 

的关系如下:

Matchups.HomeID/Matchups.VisitorID = Teams.ID 
Matchups.PeriodID = Periods.ID 
MatchupResults.MatchupID = Matchups.ID 
UserPicks.MatchupID = Matchups.ID 
UserPicks.UserID = User.ID 

我想获得(英文)是:

所有用户,无论他们是否无论他们是否有成绩,都做出了挑战和所有对决。如果他们有结果或选择,我希望他们显示。

我已经得到这个查询来获取我的对决,因为我希望他们:

select P.ID as PeriodID, 
     M.ID as MatchupID, 
     V.ID as VisitorTeam, 
     H.ID as HomeTeam, 
     MR.VisitorScore, 
     MR.HomeScore, 
     CASE WHEN (M.PointSpread <= 0) THEN 
        CASE WHEN (MR.HomeScore + M.PointSpread > MR.VisitorScore) THEN H.ID ELSE V.ID END 
      WHEN (M.PointSpread > 0) THEN 
        CASE WHEN (MR.HomeScore + M.PointSpread < MR.VisitorScore) THEN V.ID ELSE H.ID END 
      ELSE NULL 
     END AS TeamThatCoveredSpread 
from Matchups M 
left outer join MatchupResults MR ON MR.MatchupID = M.ID 
inner join Teams V ON V.ID = M.VisitorID 
inner join Teams H ON H.ID = M.HomeID 
inner join Periods P ON P.ID = M.PeriodID 

但是我有包括用户和他们的选秀权的麻烦 - 不管我尝试它让我的过滤结果只有用户选择的游戏。

因此,如果有10用户我选择1对决,我应该看到所有10个用户以及一个TeamID作为自己挑选或NULL这意味着他们没有做一挑的那场比赛。

更新:对于上面的查询的样本结果与简单指定期限1:

enter image description here

+0

我想你在找什么这里是一个十字(笛卡尔)加入 –

+1

@EricPetroelje不,他正在寻找一个'LEFT JOIN'而不是可空值。 – Matthew

+1

@TerryR我开始为你建立样本数据,并且我发现了一些我没有得到的东西。你如何确定用户在比赛中选择了哪支球队?我看到UserPicks如何包含UserID和matchupId,但它是否也表示主页/访客或团队ID? –

回答

0

我回答我的问题,感谢您的建议,并标明了每个答案和征求意见你的时间。

谢谢您的宝贵时间,这里就是答案和结果集为一个周期/用户(仅适用于简单过滤这里):

insert #UserMatchups 
select U.ID, 
     M.ID, 
     M.VisitorID, 
     M.HomeID, 
     M.HomeSpread 
from Users U, Matchups M 
where PeriodID = @PeriodID 

select M.UserID, 
     M.MatchupID, 
     CASE WHEN (M.Spread <= 0) THEN 
        CASE WHEN (MR.HomeScore + M.Spread > MR.VisitorScore) THEN M.HomeID ELSE M.VisitorID END 
      WHEN (M.Spread > 0) THEN 
        CASE WHEN (MR.HomeScore + M.Spread < MR.VisitorScore) THEN M.VisitorID ELSE M.HomeID END 
      ELSE NULL 
     END AS TeamThatCoveredSpread, 
     UP.TeamID AS UserPick 
from #UserMatchups M 
left outer join MatchupResults MR ON MR.MatchupID = M.MatchupID 
left outer join UserPicks UP ON UP.UserID = M.UserID and UP.MatchupID = M.MatchupID 
where M.UserID = 1 

enter image description here

1

这里的问题是,你有INNER JOIN S的取决于比赛的LEFT OUTER JOIN如此,当然,如果有没有你的LEFT OUTER JOIN的结果,那么INNER JOIN无法返回结果。
你需要消除你INNER JOIN因为他们需要在MatchupResults

数据使他们每个人的LEFT OUTER JOIN然后把他们JOIN条件是这样的WHERE子句中....

WHERE 
    (M.[VisitorID] IS NULL OR V.[ID] = M.[VisitorID]) 
    AND (M.[HomeID] IS NULL OR H.[ID] = M.[HomeID]) 
    AND (M.[PeriodID] IS NULL OR P.ID = M.[PeriodID]) 

所以,现在你JOIN将继续,但只有当MatchupResultsJOIN ed

+0

嗯,我似乎无法得到它的工作。我是疯了吗,还是应该这个代码不给我所有的用户,不管他们是否有选择? '从用户U选择U.ID,UP.TeamID 左外连接UserPicks UP UP.UserID = U.ID' – Terry

+1

@TerryR该代码应该为您提供所有用户,无论他们是否有选择。你有'WHERE'的情况吗? – Matthew

+0

可悲的是,没有这是整个查询,我只是让用户与挑选匹配。我期待有些用户选择'null'。 – Terry

1

我认为你应该从用户开始,然后左加入。如果你真的想要INNER JOIN,你可以这样做,但你需要把它放在Paranes内。在JOIN CLAUSE中加入@Matchupid也可能是一个好主意,因为这样你不必担心拿起其他比赛。

这应该工作(分析,但未经测试)

SELECT 
    P.ID as PeriodID, 
    M.ID as MatchupID, 
    V.ID as VisitorTeam, 
    H.ID as HomeTeam, 
    MR.VisitorScore, 
    MR.HomeScore, 
    CASE WHEN (M.PointSpread <= 0) THEN 
       CASE WHEN (MR.HomeScore + M.PointSpread > MR.VisitorScore) THEN H.ID ELSE V.ID END 
     WHEN (M.PointSpread > 0) THEN 
       CASE WHEN (MR.HomeScore + M.PointSpread < MR.VisitorScore) THEN V.ID ELSE H.ID END 
     ELSE NULL 
    END AS TeamThatCoveredSpread 
FROM users u 
     LEFT JOIN userpicks up 
     ON u.id = up.user_id 
     LEFT JOIN matchups m 
     ON up.matchupid = m.id 
      AND up.matchupid = @Matchupid 
     LEFT OUTER JOIN (matchupresults mr 
         INNER JOIN teams v 
          ON v.id = m.visitorid 
         INNER JOIN teams h 
          ON h.id = m.homeid 
         INNER JOIN periods p 
          ON p.id = m.periodid) 
     ON mr.matchupid = m.id 
+0

嗨康拉德,它不会运行它不喜欢'左外连接'子查询中的'm'标识符 – Terry

+0

哦,我需要在一次超过1场比赛,我实际上希望在特定时间段内的所有比赛。 – Terry

+0

你能否提供一些样本数据以及样本输出。 –

1

这个怎么样:

;WITH matchups (periodid, matchupid, vistortteam,HomeTeam,VisitorScore, HomeScore) 
(
SELECT P.ID AS PeriodID 
, M.ID AS MatchupID 
, V.ID AS VisitorTeam 
, H.ID AS HomeTeam 
, MR.VisitorScore 
, MR.HomeScore 
,CASE WHEN (M.PointSpread <= 0) 
     THEN 
        CASE WHEN (MR.HomeScore + M.PointSpread > MR.VisitorScore) 
         THEN H.ID 
        ELSE V.ID END     
     WHEN (M.PointSpread > 0) 
     THEN 
      CASE WHEN (MR.HomeScore + M.PointSpread < MR.VisitorScore) 
       THEN V.ID 
      ELSE H.ID END    
     ELSE NULL   
     END AS TeamThatCoveredSpread 
FROM Matchups M 
LEFT OUTER JOIN MatchupResults MR ON MR.MatchupID = M.ID 
INNER JOIN Teams V ON V.ID = M.VisitorID 
INNER JOIN Teams H ON H.ID = M.HomeID 
INNER JOIN Periods P ON P.ID = M.PeriodID 
) 

SELECT * 
FROM USERS u 
JOIN USERPIcks up ON u.id = up.userid 
LEFT JOIN matchups m ON m.MatchupID = up.MatchupID 
+0

在我有机会看到这个答案之前,我解决了我的问题。我不知道它是否有效,但它看起来与我仅以相反的顺序相似。谢谢你的建议。 – Terry