MySQL过滤多对多

时间:2014-12-14 04:52:05

标签: mysql

我有以下表格:

CREATE TABLE `job_requirements` (
  `job_id` INT(10) UNSIGNED NOT NULL,
  `course_id` INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (`job_id`,`course_id`)
)

CREATE TABLE `courses_completed` (
  `courseId` INT(10) UNSIGNED NOT NULL,
  `userId` INT(10) UNSIGNED NOT NULL,
  `completionDate` BIGINT(20) UNSIGNED NOT NULL,
  `completionStatus` INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (`courseId`,`userId`,`completionDate`)
)

用户可以使用各种completionStatuses多次完成课程。工作可以有多个要求。如何获得已完成(completionStatus = 1)所有必修课程的所有用户的列表?

我提出的最好的是一个查询,它返回用户完成了多少必需的,未过期的课程:

SELECT COUNT(*) FROM 
    (
        SELECT courseId FROM courses_completed
        INNER JOIN courses ON courseId = courses.id
        WHERE completionStatus = 1
        AND courseId IN (
            SELECT course_id FROM job_requirements
            WHERE job_id = 1)
        AND userId = 23
        AND (FROM_UNIXTIME(completionDate)
             + INTERVAL expiration_days DAY
             + INTERVAL expiration_months MONTH
             + INTERVAL expiration_years YEAR) > NOW()
        GROUP BY courseId
    ) AS sub;

一个返回已完成任何所需课程的用户列表的查询:

SELECT userId
FROM courses_completed WHERE courseID 
IN 
(
    SELECT course_id 
    FROM job_requirements
    WHERE job_id = 1
) GROUP BY userId;

我无法弄清楚如何将两者结合起来,以便将第二个查询中每行的userId传递给第一个查询

1 个答案:

答案 0 :(得分:1)

使用JOIN

SELECT userId
FROM (
    SELECT userId, COUNT(*) AS courses_completed
    FROM courses_completed AS cc
    JOIN job_requirements AS jr ON cc.courseID = jr.courseID
    WHERE jr.job_id = 1
    AND cc.completionStatus = 1
    AND (FROM_UNIXTIME(completionDate)
         + INTERVAL expiration_days DAY
         + INTERVAL expiration_months MONTH
         + INTERVAL expiration_years YEAR) > NOW()
    GROUP BY userId) AS u
JOIN (
    SELECT COUNT(*) AS courses_required
    FROM job_requirements
    WHERE job_id = 1) AS j
ON u.courses_completed = j.courses_required

您也可以在没有JOIN的情况下执行此操作,但此结构允许您将其扩展到多个作业。从job_id = 1 SELECT WHERE clauses, and add it to the GROUP BY and ON`条款中取clauses, as well as the final