我有一个包含表格的数据库: 用户,user_courses,课程和course_categories
结构类似于下图所示:
USERS ------------------------------------------------------------ id username ------------------------------------------------------------ 1 john 2 amy 3 sarah 4 james 5 nick USER_COURSES ------------------------------------------------------------ user_id course_id ------------------------------------------------------------ 1 2 1 3 1 4 2 2 3 1 4 3 5 4 5 5 COURSES ------------------------------------------------------------ id, course_category_id course_name ------------------------------------------------------------ 1 1 english language 2 1 english literature 3 2 algebra 4 3 physics 5 3 biology COURSE_CATEGORIES ------------------------------------------------------------ id category_name ------------------------------------------------------------ 1 language 2 mathematics 3 science 4 computing
我正在尝试编写一个带有user_id的查询,例如John的id为1并返回结果,显示共同的精确课程数(course_id匹配的课程)和普通课程的数量(category_id相同的课程)
因此,基于上面的示例数据库,查询应返回以下内容:
------------------------------------------------------------ user_id | username | num_exact_courses | num_common_courses ------------------------------------------------------------ 2 amy 1 0 3 sarah 0 1 4 james 1 0 5 nick 1 1
我将如何做到这一点?非常感谢这里的一些帮助。感谢
答案 0 :(得分:2)
所以基本上你在这里有一个主要的选择,从user_courses获取行..然后你必须离开加入其他行,以便没有过滤...由id组和过滤用户ID ..所以在这种情况下1为约翰..我使用COALESCE将null更改为0值,并给出最终结果集:)
SELECT
uc.user_id,
u.username,
COALESCE(t.num_exact, 0) as num_exact_courses,
COALESCE(t1.num_common, 0) as num_common_courses
FROM user_courses uc
JOIN users u ON u.id = uc.user_id
LEFT JOIN
( SELECT COUNT(course_id) AS num_exact, uc.user_id
FROM users u
LEFT JOIN user_courses uc ON u.id = uc.user_id
WHERE uc.course_id IN
( SELECT course_id -- # -- get courses where john is in
FROM user_courses
WHERE user_id = 1
) AND uc.user_id <> 1 -- # -- but make sure its not john that has the course
GROUP BY uc.user_id
) t ON t.user_id = uc.user_id
LEFT JOIN
( SELECT COUNT(*) AS num_common, uc.user_id
FROM courses c
JOIN user_courses uc ON uc.course_id = c.id
WHERE course_category_id IN
( SELECT c.course_category_id -- # -- get course categories that john has
FROM courses c
JOIN user_courses uc ON uc.course_id = c.id
WHERE uc.user_id = 1
)
AND course_id NOT IN -- # -- and make sure that the other users dont have the same course as john but are in the category
( SELECT c.id
FROM courses c
JOIN user_courses uc ON uc.course_id = c.id
WHERE uc.user_id = 1
)
GROUP BY c.id
) t1 ON t1.user_id = uc.user_id
WHERE uc.user_id <> 1
GROUP BY uc.user_id;