2012-11-13 186 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表左側的接合部之前。我希望這能幫助其他人尋找這樣的答案。