1. 程式人生 > >GROUP_CONCAT,SUBSTRING_INDEX的妙用(將多條資料合併成一行,並且根據某些列的合併值做條件判斷來生成最終值)

GROUP_CONCAT,SUBSTRING_INDEX的妙用(將多條資料合併成一行,並且根據某些列的合併值做條件判斷來生成最終值)

(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;