【问题标题】:Access main table data from within subquery从子查询中访问主表数据
【发布时间】:2014-10-02 19:59:16
【问题描述】:

假设我有一个 'users' 和 'courses' 表,并且这两个表通过 'user_courses' 表相关。这允许 1 个用户拥有许多课程等。

我的 users 表包含 100 万用户,我想:

  • 选择特定年龄和性别的用户 和
  • 选择他们与另一个给定用户共有的确切课程数

我的方法是选择性别和年龄与我正在寻找的用户相匹配的用户,这相当容易。

接下来我执行 LEFT JOIN 并使用子查询获取所有用户的数量以及与给定用户共同的课程数量。

问题是,在子查询中,我必须再次选择所有用户,并且在子查询中不重复gender = 'female' ANDbirth_year BETWEEN '1991' AND '1993',它会选择全部 100 万用户。

选择 你。 *,matching_courses_count 从 用户你 左连接 (选择 COUNT(course_id) AS matching_courses_count, uc.user_id 从 用户你 左加入 user_courses uc ON u.id = uc.user_id 在哪里 uc.course_id IN(选择 course_id 从 用户课程 在哪里 用户 ID = 1) AND uc.user_id != 1 GROUP BY uc.user_id) matching_courses ON u.id = matching_courses.user_id 在哪里 性别 = '女性' ANDbirth_year BETWEEN '1991' 和 '1993'

SQL 小提琴:http://sqlfiddle.com/#!2/c36b8/3

有没有一种方法可以做到这一点,而不必在子查询中再次选择用户或不必在子查询中重复 where 子句?

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    这是一种在select 子句中使用相关子查询来制定查询的方法。这可确保您获得所有满足 where 条件的用户,即使没有匹配的课程。

    select u.*,
           (select count(*)
            from user_courses uc join
                 user_courses uc1
                 on uc.course_id = uc1.course_id and
                    uc.user_id = u.id and
                    uc1.user_id = 1
          ) as matching_courses_count
    from users u
    where u.gender = 'female' and
          birth_year BETWEEN 1991 AND 1993;
    

    相关子查询只是计算用户和用户 1 之间的课程数量。

    【讨论】:

    • 嗨,戈登,感谢您的回答。这将是一种干净的方法,期望尝试在子查询中访问 u.id 对我来说失败,因为“on 子句”中有未知列“u.id”。有什么想法吗?
    • @ScotCalvin 。 . .这应该与外部查询中的from users u 子句相关。如果你提出一个 SQL Fiddle,我可以让它工作。
    • 我已更新问题以包含架构的 SQL Fiddle 和我的查询。
    【解决方案2】:

    我认为你想要的可以这样完成。这个想法是你选择你感兴趣的用户。然后你就可以得到他们参加的课程。然后从课程表中获取具有相同课程 ID 的其他行,最后获取参加这些课程的用户。

    然后,在 where 子句中,您将结果限制为具有所需条件的用户。并过滤掉用户1和2相同的结果。

        select *
        from users u1
        left join user_courses uc1 
        on u1.id = uc1.user_id
        left join user_courses uc2
        on uc2.course_id = uc1.course_id
        left join users u2
        on uc2.user_id = u2.id
    
        where u1.id = 1 and
              u2.gender = 'female' and u2.birth_year between '1991' and '1993' and
              u1.id != u2.id
    

    然后您可以将此结果包装在另一个查询中,以计算共同课程的数量,如下所示:

    select id, count(*) from (
            select uc1.course_id, u2.id
            from users u1
            left join user_courses uc1 
            on u1.id = uc1.user_id
            left join user_courses uc2
            on uc2.course_id = uc1.course_id
            left join users u2
            on uc2.user_id = u2.id
    
            where u1.id = 1 and
                  u2.gender = 'female' and u2.birth_year between '1991' and '1993' and
                  u1.id != u2.id) as x
        group by id
    

    【讨论】:

    • 感谢您回答汉斯,但有几件事不见了;匹配课程的数量、我们传入的用户 ID 和最终分组的用户。很高兴听到你将如何做到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多