[英]MySQL LEFT OUTER JOIN virtual table
我正在處理一個非常復雜的查詢,讓我試着向你解釋一下。 這是我在 MySQL 數據庫中的表:
學生表
--- `students` ---
student_id first_name last_name current_status status_change_date
------------ ------------ ----------- ---------------- --------------------
1 John Doe Active NULL
2 Jane Doe Retread 2012-02-01
student_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
student_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,然后左加入最高的 course_id、s_date、e_date 和 int_date,這些學生的 s_date 從 status_change_date 開始,如果 status 為“Retread” '。 然后從students_have_optional_courses TABLE中LEFT JOIN最高的optional_courses_opcourse_id,s_date和e_date,其中students_have_optional_courses.s_date大於或等於students_have_courses.s_date並且students_have_optional_courses.e_date是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
除了一件事,一切都在工作,無論我如何形成查詢,我似乎都無法獲得最高的 student_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;
這是我自己調試時找到的答案:
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;
我需要在 LEFT JOINING 之前選擇和訂購 Students_have_optional_courses 表。 我希望這有助於任何其他機構尋找這樣的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.