Php sql计数联接表中精确或类似记录的数目

Php sql计数联接表中精确或类似记录的数目,php,mysql,sql,Php,Mysql,Sql,我有一个包含以下表格的数据库: 用户、用户课程、课程和课程类别 该结构与下图所示类似: USERS ------------------------------------------------------------ id username ------------------------------------------------------------ 1 john 2 amy 3 sarah 4 james 5

我有一个包含以下表格的数据库: 用户、用户课程、课程和课程类别

该结构与下图所示类似:

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 我正在尝试编写一个查询,该查询采用用户id,例如John的id 1,并返回结果,显示课程id匹配的普通课程中的确切课程数以及类别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
我将如何做到这一点?非常感谢您的帮助。谢谢

所以基本上这里有一个主选择,可以从用户课程中获取行。。然后你必须左键连接其他行,这样就没有过滤了。。。按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;

我不明白。。。Sarah的唯一课程ID为1,而John的课程ID为2,3,4,Sarah与John的课程ID为1,Sarah与John的课程ID为2,3,4完全匹配吗?结果似乎与我对需求的理解不符。我也迷路了。艾米和约翰都有课程id 2,但不匹配。你如何区分精确课程和普通课程?@xQbert你们都是对的,我已经更新了问题以显示正确的结果。@JohnRuddell精确课程是指课程id相同的课程,一个常见的课程是,他们没有相同的ID,但属于相同的类别。非常感谢这一点,连同解释,当然填补了我知识的一些空白。@Scottcalvin,我很高兴!感谢您快速接受!:如果您对sql还有任何疑问,我很乐意进一步解释