我正在查找特定课程的访问日志。我需要显示所有课程,即使它们不存在于日志表中。因此外连接......但在尝试(大概)LEFT OUTER
,RIGHT OUTER
,INNER
的所有变体以及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中。
答案 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