我有三个(我继承了它们)表,一个用户表,一个课程表和一个测试表,我需要从中测量用户的活动。例如,以下查询将获取其中一个集合中的用户数 -
SELECT COUNT(Users.ID), `CourseSessions`.`CourseID`
FROM `Users`
LEFT OUTER JOIN `CourseSessions`
ON `Users`.`ID` = `CourseSessions`.`UserID`
WHERE `Users`.`CredentialID` IN (2, 3)
AND `CourseSessions`.`CourseID` IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
AND `CourseSessions`.`TimeIn` BETWEEN '2012-06-01' AND '2012-12-31'
GROUP BY `CourseSessions`.`CourseID`;
结果如下 -
COUNT, CourseID
32 1
43 2
31 3
49 4
36 5
21 6
5 7
2 15
我可以将CourseSessions更改为另一组数字的TestResults。当某人刚刚参加课程或参加考试时,问题就出现了。
我需要做的是,如果用户存在于其中一个或两个表中,则计算一次。鉴于以下内容 -
User Course.courseID Test.courseID
A 1
B 1 1
C 1
courseID 1的计数应为3。
我一直在关注这个问题几个小时,我想也许我应该做一个SUM ...如果但是没有按预期工作。我已经尝试过子选择,但最终我的列太多了。总而言之,我已经在这个轴上缠绕着它。
如果两个表中的用户存在一条数据,我如何获得一次计数?
答案 0 :(得分:2)
这应该可以满足您的需求:
SELECT COUNT(CoursesTest.UserID), CourseID
FROM (
SELECT UserID, CourseID
FROM CourseSessions
WHERE TimeIn BETWEEN '2012-06-01' AND '2012-12-31'
-- extra filters on CourseSessions here
UNION
SELECT UserID, CourseID
FROM TestResults
-- extra filters on TestResults here
) AS CoursesTest
JOIN Users ON Users.ID = CoursesTest.UserID
WHERE
Users.CredentialID IN (2, 3)
AND CoursesTest.CourseID IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
GROUP BY CourseID
我认为如果您之前在CourseID
上进行过滤,即在子查询内部,则查询会更快一些。这意味着重复IN
条件,但我认为MySQL不够聪明,不能优化查询。
SELECT COUNT(CoursesTest.UserID), CourseID
FROM (
SELECT UserID, CourseID
FROM CourseSessions
WHERE TimeIn BETWEEN '2012-06-01' AND '2012-12-31'
AND CourseID IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
-- extra filters on CourseSessions here
UNION
SELECT UserID, CourseID
FROM TestResults
WHERE CourseID IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
-- extra filters on TestResults here
) AS CoursesTest
JOIN Users ON Users.ID = CoursesTest.UserID
WHERE Users.CredentialD IN (2, 3)
GROUP BY CourseID