Php Mysql:如何用不同的字段名将多行连接成一行?

Php Mysql:如何用不同的字段名将多行连接成一行?,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 请告知。我正在使用MySQL。第一步,看看MySQL中的函数,它可能会有所帮助 id Maths Scie

我在寻找这样的结果:

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

请告知。我正在使用MySQL。

第一步,看看MySQL中的函数,它可能会有所帮助

id  Maths   Science   English
-----------------------------
1   32      40 & 45   50 & 60
更新 设法达到

SELECT `id`,
       `subject`,
       group_concat( `mark`
                     ORDER BY `year` DESC
                     SEPARATOR ' & '
                   ) marks
  FROM `subjects` 
 GROUP BY `id`,
          `subject`
返回

SELECT `id`,
       IF (`subject` = 'English', `marks`, NULL) AS English,
       IF (`subject` = 'Maths', `marks`, NULL) AS Maths,
       IF (`subject` = 'Science', `marks`, NULL) AS Science
  FROM ( SELECT `id`, 
                `subject`, 
                group_concat( `mark` 
                              ORDER BY `year` DESC 
                              SEPARATOR ' & ' 
                            ) marks 
           FROM `subjects`  
          GROUP BY `id`, 
                   `subject` 
         ) x
GROUP BY `id`,
         `subject` 
但不能完全正确地将最后一个分组作为一行返回。 不知道是否有其他人可以帮助我在采取这种方法解决问题时正确地迈出最后一步。。。。通常,我会将结果返回到PHP“原样”,并在那里进行最终分组;但是一个完整的MySQL解决方案会很有趣。

As,可以给您以下结果:

+----+---------+-------+---------+
| id | English | Maths | Science |
+----+---------+-------+---------+
|  1 | 50 & 60 | NULL  | NULL    |
|  1 | NULL    | 32    | NULL    |
|  1 | NULL    | NULL  | 40 & 45 |
+----+---------+-------+---------+
3 rows in set (0.01 sec)
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;
从这个测试用例中:

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);
这将得到以下结果:

+----+---------+-------+---------+
| id | English | Maths | Science |
+----+---------+-------+---------+
|  1 | 50 & 60 | NULL  | NULL    |
|  1 | NULL    | 32    | NULL    |
|  1 | NULL    | NULL  | 40 & 45 |
+----+---------+-------+---------+
3 rows in set (0.01 sec)
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;

更新:

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

+------+---------+-------+---------+
| id   | English | Maths | Science |
+------+---------+-------+---------+
|    1 | 50 & 60 | 32    | 40 & 45 |
+------+---------+-------+---------+
1 row in set (0.01 sec)
然后,我们将能够使用
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)
最后,要按一个水平行中的所有内容进行分组,我们可以使用前面示例中使用的子查询技术:

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)
将返回以下内容:

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;

如果您希望标记和年份按降序排列,只需在纯SQL中的每个
order BY year

之后添加
DESC
关键字,或者可以使用PHP?我只需要Mysql查询。谢谢你的及时回复我马克,谢谢你的回复。我想,我需要从mysql学习更多关于CONCAT()函数的知识。谢谢你的帮助。我从丹尼尔先生那里得到了解决办法。谢谢“如果”条件也很好。我需要基于年份的结果,然后我希望显示在一个水平行中。ID主题分数年份
1英语50&60 2008&2009我需要this@subakaran:你所说的“基于年份”到底是什么意思。。。你的意思是最早的标记应该首先出现?嗨,丹尼尔,非常感谢你。我跟你核实一下。我使用五个以上的表进行连接查询,并检索与您类似的结果。像你的结果一样,我想显示300多行。那么有没有可能像这样展示呢。现在我无法测试。因为Project在我的office本地服务器中有。你觉得执行时间怎么样。那么你也可以显示年份。谢谢你的帮助。好极了丹尼尔。我确实需要你最后的回答。你完全满足了我的想法。我喜欢最后的答案。那很好。所以现在我跌倒了,我需要学习更多。谢谢丹尼尔