2012-11-13 149 views
2

我正在处理一个非常复杂的查询,让我试着向你解释它。这里是表,我在我的MySQL数据库:MySQL LEFT OUTER JOIN虚拟表

学生表

--- `students` --- 
student_id first_name last_name current_status status_change_date 
------------ ------------ ----------- ---------------- -------------------- 
1    John   Doe   Active   NULL 
2    Jane   Doe   Retread   2012-02-01 

students_have_courses表

--- `students_have_courses` --- 
students_student_id courses_course_id s_date  e_date  int_date 
--------------------- ------------------- ---------- ---------- ----------- 
1      1     2012-01-01 2012-01-04 2012-01-05 
1      2     2012-01-05 NULL  NULL 
2      1     2012-01-10 2012-01-11 NULL 

students_have_optional_courses表

--- `students_have_optional_courses` --- 
students_student_id optional_courses_opcourse_id s_date  e_date 
--------------------- ------------------------------ ---------- ---------- 
1      1        2012-01-02 2012-01-03 
1      1        2012-01-06 NULL 
1      5        2012-01-07 NULL 

这里是我的查询到目前为止

SELECT 
    `students_and_courses`.student_id, 
    `students_and_courses`.first_name, 
    `students_and_courses`.last_name, 
    `students_and_courses`.courses_course_id, 
    `students_and_courses`.s_date, 
    `students_and_courses`.e_date, 
    `students_and_courses`.int_date, 
    `students_have_optional_courses`.optional_courses_opcourse_id, 
    `students_have_optional_courses`.s_date, 
    `students_have_optional_courses`.e_date 
FROM (
    SELECT 
    `c_s_a_s`.student_id, 
    `c_s_a_s`.first_name, 
    `c_s_a_s`.last_name, 
    `c_s_a_s`.courses_course_id, 
    `c_s_a_s`.s_date, 
    `c_s_a_s`.e_date, 
    `c_s_a_s`.int_date 
FROM (
    SELECT 
     `students`.student_id, 
     `students`.first_name, 
     `students`.last_name, 
     `students_have_courses`.courses_course_id, 
     `students_have_courses`.s_date, 
     `students_have_courses`.e_date, 
     `students_have_courses`.int_date 
    FROM 
     `students` 
     LEFT OUTER JOIN `students_have_courses` 
     ON (
      `students_have_courses`.`students_student_id` = `students`.`student_id` AND  (( 
      `students_have_courses`.`s_date` >= `students`.`status_change_date` AND 
      `students`.current_status = 'Retread') OR 
      `students`.current_status = 'Active') 
     ) 
     WHERE 
     `students`.current_status = 'Active' OR 
     `students`.current_status = 'Retread' 
) `c_s_a_s` 
    ORDER BY 
    `c_s_a_s`.`courses_course_id` DESC 
) `students_and_courses` 
LEFT OUTER JOIN `students_have_optional_courses` 
    ON (
    `students_have_optional_courses`.students_student_id =  `students_and_courses`.student_id AND 
    `students_have_optional_courses`.s_date >= `students_and_courses`.s_date AND 
    `students_have_optional_courses`.e_date IS NULL 
) 
GROUP BY 
`students_and_courses`.student_id; 

我想要返回的是所有Active或Retread学生的student_id,first_name和last_name,然后LEFT JOIN为自s_date以来的最高course_id,s_date,e_date和int_date,因为status_change_date如果状态是'Retread'。然后LEFT JOIN最高optional_courses_opcourse_id,s_date和e_date从students_have_optional_courses表,其中students_have_optional_courses.s_date大于或等于students_have_courses.s_date和students_have_optional_courses.e_date IS NULL被返回是什么

这里:

student_id first_name last_name courses_course_id s_date  e_date  int_date  optional_courses_opcourse_id s_date_1 e_date_1 
------------ ------------ ----------- ------------------- ---------- ---------- ------------ ------------------------------ ---------- ---------- 
1    John   Doe   2     2012-01-05 NULL  NULL   1        2012-01-06 NULL 
2    Jane   Doe   NULL     NULL  NULL  NULL   NULL       NULL  NULL 

这里是我想要返回什么:

student_id first_name last_name courses_course_id s_date  e_date  int_date  optional_courses_opcourse_id s_date_1 e_date_1 
------------ ------------ ----------- ------------------- ---------- ---------- ------------ ------------------------------ ---------- ---------- 
1    John   Doe   2     2012-01-05 NULL  NULL   5        2012-01-07 NULL 
2    Jane   Doe   NULL     NULL  NULL  NULL   NULL       NULL  NULL 

一切工作,除了一两件事,我似乎无法得到最高students_have_optional _courses.optional_courses_opcourse_id无论我如何形成查询

对不起,我刚刚解决这个问题后写了这一切,我认为这有助于我想到的解决方案。

下面是解查询:

SELECT 
     `students_and_courses`.student_id, 
     `students_and_courses`.first_name, 
     `students_and_courses`.last_name, 
     `students_and_courses`.courses_course_id, 
     `students_and_courses`.s_date, 
     `students_and_courses`.e_date, 
     `students_and_courses`.int_date, 
     `students_optional_courses`.optional_courses_opcourse_id, 
     `students_optional_courses`.s_date, 
     `students_optional_courses`.e_date 
    FROM (
     SELECT 
     `c_s_a_s`.student_id, 
     `c_s_a_s`.first_name, 
     `c_s_a_s`.last_name, 
     `c_s_a_s`.courses_course_id, 
     `c_s_a_s`.s_date, 
     `c_s_a_s`.e_date, 
     `c_s_a_s`.int_date 
     FROM (
     SELECT 
      `students`.student_id, 
      `students`.first_name, 
      `students`.last_name, 
      `students_have_courses`.courses_course_id, 
      `students_have_courses`.s_date, 
      `students_have_courses`.e_date, 
      `students_have_courses`.int_date 
     FROM 
      `students` 
      LEFT OUTER JOIN `students_have_courses` 
      ON (
       `students_have_courses`.`students_student_id` = `students`.`student_id` AND (( 
       `students_have_courses`.`s_date` >= `students`.`status_change_date` AND 
       `students`.current_status = 'Retread') OR 
       `students`.current_status = 'Active') 
      ) 
      WHERE 
      `students`.current_status = 'Active' OR 
      `students`.current_status = 'Retread' 
    ) `c_s_a_s` 
     ORDER BY 
     `c_s_a_s`.`courses_course_id` DESC 
    ) `students_and_courses` 
    LEFT OUTER JOIN (
     SELECT 
     * 
     FROM 
     `students_have_optional_courses` 
     ORDER BY 
     `students_have_optional_courses`.optional_courses_opcourse_id DESC 
    ) `students_optional_courses` 
     ON (
     `students_optional_courses`.students_student_id = `students_and_courses`.student_id AND 
     `students_optional_courses`.s_date >= `students_and_courses`.s_date AND 
     `students_optional_courses`.e_date IS NULL 
    ) 
    GROUP BY 
    `students_and_courses`.student_id; 
+0

然后添加您的解决方案作为答案,请接受它。它可能会帮助其他人。 – fancyPants

+0

感谢@tombom的+1 – amaster

回答

2

这里是我发现的,而这在调试自己的答案:

SELECT 
     `students_and_courses`.student_id, 
     `students_and_courses`.first_name, 
     `students_and_courses`.last_name, 
     `students_and_courses`.courses_course_id, 
     `students_and_courses`.s_date, 
     `students_and_courses`.e_date, 
     `students_and_courses`.int_date, 
     `students_optional_courses`.optional_courses_opcourse_id, 
     `students_optional_courses`.s_date, 
     `students_optional_courses`.e_date 
    FROM (
     SELECT 
     `c_s_a_s`.student_id, 
     `c_s_a_s`.first_name, 
     `c_s_a_s`.last_name, 
     `c_s_a_s`.courses_course_id, 
     `c_s_a_s`.s_date, 
     `c_s_a_s`.e_date, 
     `c_s_a_s`.int_date 
     FROM (
     SELECT 
      `students`.student_id, 
      `students`.first_name, 
      `students`.last_name, 
      `students_have_courses`.courses_course_id, 
      `students_have_courses`.s_date, 
      `students_have_courses`.e_date, 
      `students_have_courses`.int_date 
     FROM 
      `students` 
      LEFT OUTER JOIN `students_have_courses` 
      ON (
       `students_have_courses`.`students_student_id` = `students`.`student_id` AND (( 
       `students_have_courses`.`s_date` >= `students`.`status_change_date` AND 
       `students`.current_status = 'Retread') OR 
       `students`.current_status = 'Active') 
      ) 
      WHERE 
      `students`.current_status = 'Active' OR 
      `students`.current_status = 'Retread' 
    ) `c_s_a_s` 
     ORDER BY 
     `c_s_a_s`.`courses_course_id` DESC 
    ) `students_and_courses` 
    LEFT OUTER JOIN (
     SELECT 
     * 
     FROM 
     `students_have_optional_courses` 
     ORDER BY 
     `students_have_optional_courses`.optional_courses_opcourse_id DESC 
    ) `students_optional_courses` 
     ON (
     `students_optional_courses`.students_student_id = `students_and_courses`.student_id AND 
     `students_optional_courses`.s_date >= `students_and_courses`.s_date AND 
     `students_optional_courses`.e_date IS NULL 
    ) 
    GROUP BY 
    `students_and_courses`.student_id; 

我需要来选择和订购students_have_optional_courses表左侧的接合部之前。我希望这能帮助其他人寻找这样的答案。