php - Mysql:如何将多行连接成具有不同字段名称的单行?

标签 php mysql

id  Subject   mark   Year
-------------------------
1   Maths      32    2008
1   Science    40    2009
1   Science    45    2008
1   English    50    2009
1   English    60    2008

我正在寻找这样的结果:

id  Maths   Science   English
-----------------------------
1   32      40 & 45   50 & 60

请指教。我正在使用 MySQL。

最佳答案

作为@Mark suggested , GROUP_CONCAT()可以给你以下结果:

SELECT   id, subject, GROUP_CONCAT(mark SEPARATOR ' & ') marks
FROM     results 
GROUP BY id, subject;
+------+---------+---------+
| id   | subject | marks   |
+------+---------+---------+
|    1 | English | 50 & 60 |
|    1 | Maths   | 32      |
|    1 | Science | 40 & 45 |
+------+---------+---------+
3 rows in set (0.00 sec)

来自这个测试用例:

CREATE TABLE results (id int, subject varchar(10), mark int);

INSERT INTO results VALUES (1, 'Maths', 32);
INSERT INTO results VALUES (1, 'Science', 40);
INSERT INTO results VALUES (1, 'Science', 45);
INSERT INTO results VALUES (1, 'English', 50);
INSERT INTO results VALUES (1, 'English', 60);

然而,另一种解决问题的方法是对每个主题使用 as 子查询:

SELECT    r.id,
          (SELECT   GROUP_CONCAT(r_eng.mark SEPARATOR ' & ')
           FROM     results r_eng
           WHERE    r_eng.subject = 'English' AND r_eng.id = r.id) English,
          (SELECT   GROUP_CONCAT(r_eng.mark SEPARATOR ' & ') 
           FROM     results r_eng
           WHERE    r_eng.subject = 'Maths' AND r_eng.id = r.id) Maths,
          (SELECT   GROUP_CONCAT(r_eng.mark SEPARATOR ' & ') 
           FROM     results r_eng
           WHERE    r_eng.subject = 'Science' AND r_eng.id = r.id) Science
FROM      results r
GROUP BY  r.id;

这将给出以下结果:

+------+---------+-------+---------+
| id   | English | Maths | Science |
+------+---------+-------+---------+
|    1 | 50 & 60 | 32    | 40 & 45 |
+------+---------+-------+---------+
1 row in set (0.01 sec)

更新:

除了注释之外,您似乎需要考虑 year 字段。幸运的是,GROUP_CONCAT() 函数带有一个我们可以使用的 ORDER BY 子句。让我们从一个带有年份字段的新测试用例开始:

CREATE TABLE results (id int, subject varchar(10), mark int, year int);

INSERT INTO results VALUES (1, 'Maths', 32, 2008);
INSERT INTO results VALUES (1, 'Science', 40, 2009);
INSERT INTO results VALUES (1, 'Science', 45, 2008);
INSERT INTO results VALUES (1, 'English', 50, 2009);
INSERT INTO results VALUES (1, 'English', 60, 2008);

SELECT * FROM results;
+------+---------+------+------+
| id   | subject | mark | year |
+------+---------+------+------+
|    1 | Maths   |   32 | 2008 |
|    1 | Science |   40 | 2009 |
|    1 | Science |   45 | 2008 |
|    1 | English |   50 | 2009 |
|    1 | English |   60 | 2008 |
+------+---------+------+------+
5 rows in set (0.00 sec)

然后我们就可以使用 GROUP_CONCAT() 函数和 ORDER BY 子句,如下所示:

SELECT   id, 
         subject, 
         GROUP_CONCAT(mark ORDER BY year SEPARATOR ' & ') marks, 
         GROUP_CONCAT(year ORDER BY year SEPARATOR ' & ') years
FROM     results 
GROUP BY id, subject;

+------+---------+---------+-------------+
| id   | subject | marks   | years       |
+------+---------+---------+-------------+
|    1 | English | 60 & 50 | 2008 & 2009 |
|    1 | Maths   | 32      | 2008        |
|    1 | Science | 45 & 40 | 2008 & 2009 |
+------+---------+---------+-------------+
3 rows in set (0.00 sec)

最后,要GROUP BY水平行中的所有内容,我们可以使用我们在前面示例中使用的子查询技术:

SELECT    r.id,
          (SELECT  GROUP_CONCAT(r_eng.mark ORDER BY year SEPARATOR ' & ') 
           FROM    results r_eng
           WHERE   r_eng.subject = 'English' AND r_eng.id = r.id) English,
          (SELECT  GROUP_CONCAT(r_eng.year ORDER BY year SEPARATOR ' & ')
            FROM   results r_eng
            WHERE  r_eng.subject = 'English' AND r_eng.id = r.id) Years_English,
          (SELECT  GROUP_CONCAT(r_eng.mark ORDER BY year SEPARATOR ' & ')
           FROM    results r_eng
           WHERE   r_eng.subject = 'Maths' AND r_eng.id = r.id) Maths,
          (SELECT  GROUP_CONCAT(r_eng.year ORDER BY year SEPARATOR ' & ')
            FROM   results r_eng
            WHERE  r_eng.subject = 'Maths' AND r_eng.id = r.id) Years_Maths,
          (SELECT  GROUP_CONCAT(r_eng.mark ORDER BY year SEPARATOR ' & ')
           FROM    results r_eng
           WHERE   r_eng.subject = 'Science' AND r_eng.id = r.id) Science,
          (SELECT  GROUP_CONCAT(r_eng.year ORDER BY year SEPARATOR ' & ')
            FROM   results r_eng
            WHERE  r_eng.subject = 'Science' AND r_eng.id = r.id) Years_Science
FROM      results r
GROUP BY  r.id;

这将返回以下内容:

+----+---------+---------------+-------+-------------+---------+---------------+
| id | English | Years_English | Maths | Years_Maths | Science | Years_Science |
+----+---------+---------------+-------+-------------+---------+---------------+
|  1 | 60 & 50 | 2008 & 2009   | 32    | 2008        | 45 & 40 | 2008 & 2009   |
+----+---------+---------------+-------+-------------+---------+---------------+
1 row in set (0.01 sec)

如果您希望标记和年份按降序排列,您可以在每个 ORDER BY year 之后简单地添加 DESC 关键字。

关于php - Mysql:如何将多行连接成具有不同字段名称的单行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3015786/

相关文章:

javascript - 添加一行 PHP header ('location...' ) 时,Highcharts 不显示

MySQL 集群(主/从)和 Hibernate

mysql - MySQL 一天内多个项目的单独计数

php - html/css/php 选择导航

php - 相同和不同表中不同 id 的多个联接

php - 从 SQL select sum group by 到 Yii 框架中的 Active Record 2

javascript - 按下特定列表的按钮后使用ajax更新特定列表<li>

php - 尝试使用Ajax和PHP制作登录表单

php - 在 MySQL 中管理删除时的唯一 ID

python - 当不同用户之间的底层表更改时,MySQL View 不会更新