2010-03-17 49 views
2

我有两个表,一个是论坛线程表。它有最后的发布日期列。帮助SQL在两个表上加入

另一个表具有PostID,UserId和DateViewed。

我想加入这些表,所以我可以为当前用户比较DateViewed和LastPostDate。但是,如果他们从未查看过线程,则第二个表中不会有一行。

这似乎很容易,但我不能包裹我的头。建议请。

在此先感谢。

+0

尝试左连接。一直在使用左外部 – bladefist 2010-03-17 01:58:24

+0

'外部'是多余的。这与'LEFT JOIN'完全相同。 – Aaronaught 2010-03-17 02:01:12

+0

这些都是一样的。 – 2010-03-17 02:01:16

回答

2

什么是你试图做的具体 - 确定是否有未读的帖子?

你只需要使用一个外连接:

SELECT p.PostID, p.LastPostDate, ..., 
    CASE 
     WHEN v.DateViewed IS NULL OR v.DateViewed < p.LastPostDate THEN 1 
     ELSE 0 
    END AS Unread 
FROM Posts p 
LEFT JOIN PostViews v 
    ON v.PostID = p.PostID 
    AND v.UserID = @UserID 

请注意,我已经放置在JOIN条件UserID测试;如果将它放在WHERE谓词中,那么您将得不到结果,因为PostViews表中将没有匹配的行。

+0

这工作完美谢谢 – bladefist 2010-03-17 02:05:41

+0

好吧,好...我正在重读您的问题,并且感到困惑,因为我找不到线程和帖子之间的任何连接,但我猜测你知道了! – Aaronaught 2010-03-17 02:07:31

1

所以你在想是这样的:

SELECT t.UserID, t.PostID, t.LastPostDate, v.DateViewed 
FROM dbo.Threads t 
LEFT JOIN dbo.Views v ON v.PostID = t.PostID 
        AND v.UserID = t.UserID 
WHERE t.UserID = @user; 

v.DateViewed将是NULL,如果有在视图中没有对应的行。

如果你有大量的图的行,你可能更愿意做这样的事情:

SELECT t.UserID, t.PostID, t.LastPostDate, v.DateViewed 
FROM dbo.Threads t 
CROSS APPLY (SELECT MAX(vw.DateViewed) as DateViewed 
      FROM dbo.Views vw 
      WHERE vw.PostID = t.PostID 
       AND vw.UserID = t.UserID 
      ) v 
WHERE t.UserID = @user; 
+0

表t没有userid。 UserId只在表中持有上次查看线程的时间。 这将应用在执行时的位置 – bladefist 2010-03-17 02:02:48

0

的关键是使用LEFT JOIN,这将导致不存在行右侧上来因为所有NULL

SELECT threads.lastpostdate, posts.dateviewed 
FROM threads 
LEFT JOIN posts 
    ON threads.id=posts.postid