sql计数连接表中的精确或类似记录的数量

时间:2014-08-01 16:56:45

标签: php mysql sql

我有一个包含表格的数据库: 用户,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

我将如何做到这一点?非常感谢这里的一些帮助。感谢

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;

DEMO