【问题标题】:sql count number of exact or similar records in join tablessql count 连接表中确切或相似记录的数量
【发布时间】:2014-08-01 16:56:45
【问题描述】:

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

结构类似于下图:

用户 -------------------------------------------------- ---------- id 用户名 -------------------------------------------------- ---------- 1 约翰 2 艾米 3 莎拉 4 詹姆斯 5 尼克 USER_COURSES -------------------------------------------------- ---------- user_id course_id -------------------------------------------------- ---------- 1 2 1 3 1 4 2 2 3 1 4 3 5 4 5 5 培训班 -------------------------------------------------- ---------- id, course_category_id course_name -------------------------------------------------- ---------- 1 1 英语 2 1 英国文学 3 2 代数 4 3物理 5 3 生物学 课程类别 -------------------------------------------------- ---------- id 类别名称 -------------------------------------------------- ---------- 1 种语言 2 数学 3 科学 4 计算

我正在尝试编写一个带有 user_id 的查询,例如id 1 为 John 并返回显示共同课程的确切数量(course_id 匹配的课程)和共同课程的数量(category_id 相同的课程)的结果

所以基于上面的示例数据库,查询应该返回以下内容:

-------------------------------------------------- ---------- 用户 ID |用户名 | num_exact_courses | num_common_courses -------------------------------------------------- ---------- 2 艾米 1 0 3 莎拉 0 1 4 詹姆斯 1 0 5 尼克 1 1

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

【问题讨论】:

  • 我不明白... 唯一 course_ID 为 1 的 Sarah 与课程为 (2,3,4) 的 John 不共享任何课程是完全匹配的吗?结果似乎与我对要求的理解不符。
  • 我也迷路了。 Amy 和 John 都有 course_id 2 但不匹配。
  • 精确课程和普通课程如何区分?
  • @xQbert 你说的都对,我已经更新了问题以显示正确的结果。
  • @JohnRuddell 精确课程是 course_id 相同的课程,普通课程是 ID 不同但属于同一类别的课程。

标签: php mysql sql


【解决方案1】:

所以基本上在这里你有一个从 user_courses 获取行的主选择.. 然后你必须离开加入其他行以便没有过滤......按 id 分组并按用户 id 过滤.. 所以在这种情况下 1 为 John .. 我使用 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

【讨论】:

  • 非常感谢您的解释,以及解释,确实填补了我知识上的一些空白。
  • @ScotCalvin 很高兴!感谢您迅速接受! :) 如果您对 sql 有任何疑问,我很乐意为您解释更多
猜你喜欢
  • 2020-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-20
  • 1970-01-01
  • 2014-08-17
  • 1970-01-01
  • 2021-10-27
相关资源
最近更新 更多