SQL Server 2005 RIGHT OUTER JOIN无法正常工作

时间:2010-05-20 13:54:32

标签: sql sql-server-2005 inner-join outer-join

我正在查找特定课程的访问日志。我需要显示所有课程,即使它们不存在于日志表中。因此外连接......但在尝试(大概)LEFT OUTERRIGHT OUTERINNER的所有变体以及SQL代码中表的放置之后,我无法得到我的结果。

这就是我正在运行的内容:

SELECT   (a.first_name+' '+a.last_name) instructor,
            c.course_id,
            COUNT(l.access_date) course_logins,
            a.logins system_logins,
            MAX(l.access_date) last_course_login,
            a.last_login last_system_login
FROM       lsn_logs l RIGHT OUTER JOIN courses c ON l.course_id = c.course_id,
            accounts a
WHERE     l.object_id = 'LOGIN' 
            AND c.course_type = 'COURSE' 
            AND c.course_id NOT LIKE '%TEST%' 
            AND a.account_rights > 2
            AND l.user_id = a.username
            AND ((a.first_name+' '+a.last_name) = c.instructor)
GROUP BY    c.course_id, 
            a.first_name, 
            a.last_name,
            a.last_login,
            a.logins,
            c.instructor
ORDER BY    a.last_name,
            a.first_name,
            c.course_id,
            course_logins DESC

WHERE子句中是否存在阻止我获取lsn_logs中不存在的course_id的内容?这是我加入赌桌的方式吗?

同样,简而言之,我想要所有的course_id,无论它们是否存在于lsn_logs中。

5 个答案:

答案 0 :(得分:8)

  

WHERE子句中是否存在阻止我获取lsn_logs中不存在的course_id的内容?

是的,是的。

您在WHERE子句中使用了相等条件,可以有效地过滤掉NULL生成的OUTER JOIN行。

<强>更新

SELECT  c.instructor,
        c.course_id,
        l.course_logins,
        a.logins system_logins,
        l.last_course_login,
        a.last_login last_system_login
FROM    courses с
JOIN    accounts a
ON      a.first_name + ' ' + a.last_name = c.instructor
CROSS APPLY
        (
        SELECT  COALESCE(COUNT(access_date), 0) course_logins,
                MAX(access_date) last_course_login
        FROM    lsn_logs l
        WHERE   l.object_id = 'LOGIN'
                AND l.course_id = c.course_id
                AND l.user_id = a.username
        ) l
WHERE   c.course_type = 'COURSE' 
        AND c.course_id NOT LIKE '%TEST%' 
        AND a.account_rights > 2
ORDER BY
        a.last_name,
        a.first_name,
        c.course_id,
        course_logins DESC

答案 1 :(得分:2)

要扩展Quassnoi的好答案,要使外部联接起作用,您可以更改:

AND l.user_id = a.username

要:

AND (l.user_id is null OR l.user_id = a.username)

答案 2 :(得分:2)

SELECT...    
FROM courses c
     INNER JOIN accounts a
        ON (a.first_name+' '+a.last_name) = c.instructor
     LEFT OUTER JOIN lsn_logs l
        ON l.course_id = c.course_id
        AND l.user_id = a.username
        AND l.object_id = 'LOGIN' 
WHERE c.course_type = 'COURSE'  
    AND c.course_id NOT LIKE '%TEST%'
    AND a.account_rights > 2 
    AND a.logins > 0 
GROUP BY...
ORDER BY...

答案 3 :(得分:1)

SQL Server 2005 RIGHT OUTER JOIN肯定有效! :)

以下内容(我做了一些假设)?:

除去

AND l.user_id = a.username 

并将联接更改为

dbo.courses c
LEFT OUTER JOIN lsn_logs l
ON c.course_id = l.course_id
LEFT OUTER JOIN accounts a
ON l.user_id = a.username 

并为lsn_logs和accounts字段添加一些空检查,例如:

(l.object_id IS NULL OR l.object_id = 'LOGIN')

答案 4 :(得分:0)

最终工作

Joe R建议的空检查解决了Quassnoi提到的问题

SELECT   (a.first_name+' '+a.last_name) instructor,
            c.course_id,
            COUNT(l.access_date) course_logins,
            a.logins system_logins,
            MAX(l.access_date) last_course_login,
            a.last_login last_system_login
FROM       lsn_logs l RIGHT OUTER JOIN courses c ON l.course_id = c.course_id,
            accounts a
WHERE     (l.object_id IS NULL OR l.object_id = 'LOGIN') 
            AND c.course_type = 'COURSE' 
            AND c.course_id NOT LIKE '%TEST%' 
            AND a.account_rights > 2
            AND (l.user_id = a.username OR l.user_id IS NULL)
            AND ((a.first_name+' '+a.last_name) = c.instructor)
            AND a.logins > 0
GROUP BY    c.course_id, 
            a.first_name, 
            a.last_name,
            a.last_login,
            a.logins,
            c.instructor
ORDER BY    a.last_name,
            a.first_name,
            c.course_id,
            course_logins DESC