GROUP_CONCAT,SUBSTRING_INDEX的妙用(將多條資料合併成一行,並且根據某些列的合併值做條件判斷來生成最終值)
阿新 • • 發佈:2018-12-18
(1)不做處理:
SELECT e.class_id AS class_id, c.course_name AS class_name, u.stuNum AS stu_num, u.USER_NAME AS student_name, u.department AS department, ( SELECT s.SUBJECT_NAME FROM exam_subject s WHERE s.SUBJECT_ID = e.SUBJECT_ID ) AS subject_name, e.paper_name, p.score AS paper_score, e.update_time, ( CASE WHEN e.update_time BETWEEN '2018-11-01 00:00:00' AND '2018-11-30 23:59:59' THEN '第1次' WHEN e.update_time BETWEEN '2018-12-05 00:00:00' AND '2018-12-07 23:59:59' THEN '第2次' ELSE 0 END ) test_count, e.user_score AS user_score FROM edu_course c, exam_exampaper_record e, exam_exampaper p, edu_user u WHERE c.course_id = e.class_id AND u.USER_ID = e.cus_id AND u.ROLE_ID = '0' AND e.subject_id = p.SUBJECT_ID AND e.paper_name = p. NAME AND p. STATUS = 0 AND e.class_id = 421 AND p.id = 17015 ORDER BY u.USER_ID;
執行結果如下:
(2)根據需求的變動,市場部想要的結果是:
那麼,要想得到上面的結果,sql到底該如何改寫呢?
請看下面改寫後的sql:
SELECT *, ( CASE WHEN LOCATE(',', t.used_time1) > 0 THEN substring_index(t.used_time1, ',', 1) WHEN LOCATE(',', t.used_time2) > 0 THEN substring_index(t.used_time2, ',', 1) ELSE t.used_time1 END ) AS first_used_time, ( CASE WHEN LOCATE(',', t.used_time1) > 0 THEN substring_index(t.used_time1, ',', - 1) WHEN LOCATE(',', t.used_time2) > 0 THEN substring_index(t.used_time2, ',' ,- 1) ELSE t.used_time2 END ) AS second_used_time, ( CASE WHEN LOCATE(',', t.accuracy1) > 0 THEN substring_index(t.accuracy1, ',', 1) WHEN LOCATE(',', t.accuracy2) > 0 THEN substring_index(t.accuracy2, ',', 1) ELSE t.accuracy1 END ) AS first_accuracy, ( CASE WHEN LOCATE(',', t.accuracy1) > 0 THEN substring_index(t.accuracy1, ',', - 1) WHEN LOCATE(',', t.accuracy2) > 0 THEN substring_index(t.accuracy2, ',' ,- 1) ELSE t.accuracy2 END ) AS second_accuracy, ( CASE WHEN LOCATE(',', t.test_time1) > 0 THEN substring_index(t.test_time1, ',', 1) WHEN LOCATE(',', t.test_time2) > 0 THEN substring_index(t.test_time2, ',', 1) ELSE t.test_time1 END ) AS time1, ( CASE WHEN LOCATE(',', t.test_time1) > 0 THEN substring_index(t.test_time1, ',', - 1) WHEN LOCATE(',', t.test_time2) > 0 THEN substring_index(t.test_time2, ',' ,- 1) ELSE t.test_time2 END ) AS time2, ( CASE WHEN LOCATE(',', t.user_score1) > 0 THEN substring_index(t.user_score1, ',', 1) WHEN LOCATE(',', t.user_score2) > 0 THEN substring_index(t.user_score2, ',', 1) ELSE t.user_score1 END ) AS test1, ( CASE WHEN LOCATE(',', t.user_score1) > 0 THEN substring_index(t.user_score1, ',', - 1) WHEN LOCATE(',', t.user_score2) > 0 THEN substring_index(t.user_score2, ',' ,- 1) ELSE t.user_score2 END ) AS test2 FROM ( SELECT e.class_id AS class_id, c.course_name AS class_name, u.user_id AS student_id, u.stuNum AS stu_num, u.USER_NAME AS student_name, u.department AS department, ( SELECT s.SUBJECT_NAME FROM exam_subject s WHERE s.SUBJECT_ID = e.SUBJECT_ID ) AS subject_name, e.paper_name paper_name, p. LEVEL AS paper_level, p.REPLY_TIME AS paper_time, ( CASE WHEN e.update_time BETWEEN '2018-11-01 00:00:00' AND '2018-11-30 23:59:59' THEN GROUP_CONCAT( e.test_time ORDER BY e.update_time ) ELSE NULL END ) AS used_time1, ( CASE WHEN e.update_time BETWEEN '2018-12-05 00:00:00' AND '2018-12-07 23:59:59' THEN GROUP_CONCAT( e.test_time ORDER BY e.update_time ) ELSE NULL END ) AS used_time2, ( CASE WHEN e.update_time BETWEEN '2018-11-01 00:00:00' AND '2018-11-30 23:59:59' THEN GROUP_CONCAT( e.accuracy ORDER BY e.update_time ) ELSE NULL END ) AS accuracy1, ( CASE WHEN e.update_time BETWEEN '2018-12-05 00:00:00' AND '2018-12-07 23:59:59' THEN GROUP_CONCAT( e.accuracy ORDER BY e.update_time ) ELSE NULL END ) AS accuracy2, p.score AS paper_score, ( CASE WHEN e.update_time BETWEEN '2018-11-01 00:00:00' AND '2018-11-30 23:59:59' THEN GROUP_CONCAT( e.update_time ORDER BY e.update_time ) ELSE NULL END ) AS test_time1, ( CASE WHEN e.update_time BETWEEN '2018-12-05 00:00:00' AND '2018-12-07 23:59:59' THEN GROUP_CONCAT( e.update_time ORDER BY e.update_time ) ELSE NULL END ) AS test_time2, ( CASE WHEN e.update_time BETWEEN '2018-11-01 00:00:00' AND '2018-11-30 23:59:59' THEN GROUP_CONCAT( user_score ORDER BY e.update_time ) ELSE 0 END ) AS user_score1, ( CASE WHEN e.update_time BETWEEN '2018-12-05 00:00:00' AND '2018-12-07 23:59:59' THEN GROUP_CONCAT( user_score ORDER BY e.update_time ) ELSE 0 END ) AS user_score2 FROM edu_course c, exam_exampaper_record e, exam_exampaper p, edu_user u WHERE c.course_id = e.class_id AND u.USER_ID = e.cus_id AND u.ROLE_ID = '0' AND e.subject_id = p.SUBJECT_ID AND e.paper_name = p. NAME AND p. STATUS = 0 AND e.class_id = 421 AND p.id = 17015 GROUP BY u.USER_ID ORDER BY u.USER_ID ) AS t;