返回

合并 MySQL 查询中连接表的行:处理重复行、动态列名和优化输出

mysql

合并 MySQL 查询中连接表的行

简介

在处理复杂的 MySQL 查询时,经常需要合并来自多个连接表的行。本文将指导你了解如何合并这些行,包括处理重复行、动态列名和使用示例输出的技巧。

合并连接表的行

要合并连接表中的行,可以使用 INNER JOINLEFT JOININNER JOIN 仅返回存在于两个表中的行,而 LEFT JOIN 返回来自左表的行,即使在右表中没有匹配的记录。

示例查询:

假设我们有以下表:

  • 学校 (id, 名称, 城市代码)
  • 学生 (id, 名字, 姓氏, 学校 id)
  • 科目 (id, 名称, 科目代码)
  • 成绩 (id, 学生 id, 科目 id, 学校 id, 班级 id, 学年, 学期)

以下查询将合并来自所有四个表的行,返回学校名称、学生姓名、科目名称和分数:

SELECT
  A.name AS school_name,
  CONCAT_WS(' ', B.firstname, B.surname) AS student_name,
  C.subject_name,
  C.ca_score,
  C.exam_score
FROM schools A
INNER JOIN students B ON A.id = B.school_id
LEFT JOIN student_score C ON C.student_id = B.id
LEFT JOIN subjects D ON D.id = C.subject_id
WHERE A.city_code = 5 AND C.academic_term = 'First' AND C.academic_year = '2023' AND C.class_id = 9;

处理重复行

如上例所示,此查询为每个学生返回多行,因为每个学生可能有多个科目。要合并这些行,可以使用 GROUP BY 子句:

SELECT
  A.name AS school_name,
  CONCAT_WS(' ', B.firstname, B.surname) AS student_name,
  GROUP_CONCAT(D.subject_name) AS subject_names,
  GROUP_CONCAT(C.ca_score) AS ca_scores,
  GROUP_CONCAT(C.exam_score) AS exam_scores
FROM schools A
INNER JOIN students B ON A.id = B.school_id
LEFT JOIN student_score C ON C.student_id = B.id
LEFT JOIN subjects D ON D.id = C.subject_id
WHERE A.city_code = 5 AND C.academic_term = 'First' AND C.academic_year = '2023' AND C.class_id = 9
GROUP BY
  A.name,
  B.firstname,
  B.surname;

动态列名

为了将每个科目代码与原始分数列名称(ca_scoreexam_score)合并或添加前缀,可以使用动态列名:

SELECT
  A.name AS school_name,
  CONCAT_WS(' ', B.firstname, B.surname) AS student_name,
  CONCAT(D.subject_name, '_ca_score') AS subject_code_ca_score,
  CONCAT(D.subject_name, '_exam_score') AS subject_code_exam_score
FROM schools A
INNER JOIN students B ON A.id = B.school_id
LEFT JOIN student_score C ON C.student_id = B.id
LEFT JOIN subjects D ON D.id = C.subject_id
WHERE A.city_code = 5 AND C.academic_term = 'First' AND C.academic_year = '2023' AND C.class_id = 9;

示例输出

此查询的输出如下:

school_name | student_name | english_ca_score | english_exam_score | maths_ca_score | maths_exam_score | physics_ca_score | physics_exam_score | chemistry_ca_score | chemistry_exam_score
St. Pet Sch | John V. Doe |       20          |         51        |         22      |          49      |        24        |          55        |         22        |          48
Merlin Sch | Jane B. Doe |       19          |         53        |         21      |          50      |        21        |          48        |         24        |          51
Belfast Sch | James P. Doe |       24          |         50        |         18      |          52      |        22        |          50        |         19        |          47

结论

合并连接表中的行可以提供一个统一的数据视图,使你能够在单个查询中获取所有必要的信息。通过使用 JOINGROUP BY 和动态列名,你可以轻松处理重复行,连接数据并优化输出。

常见问题解答

1. 何时使用 INNER JOINLEFT JOIN

  • INNER JOIN 用于返回存在于两个表中的行。
  • LEFT JOIN 用于返回来自左表的行,即使在右表中没有匹配的记录。

2. GROUP BY 子句如何处理重复行?

  • GROUP BY 子句将具有相同分组列值的重复行分组在一起。

3. 动态列名如何工作?

  • 动态列名允许你使用表达式创建新的列名称。

4. 如何在合并的查询中使用过滤条件?

  • WHERE 子句中使用过滤条件。

5. 如何提高合并查询的性能?

  • 使用适当的索引。
  • 考虑使用临时表或子查询。
  • 优化查询语法。