从单个表中只在一行中添加多行

时间:2012-07-16 17:27:52

标签: mysql sql view

如何通过mysql在一行中连接多行?

示例:

学生表

Sno.| Name  |  Subjects
1.  | ABC   |  English
2.  | ABC   |  Mathematics
3.  | ABC   |  Science
4.  | FMC |  French
5.  | ABC   |  Russian
6.  | JBC   |  French

现在我想要这种格式

Sno.| Name |   Sub1 |  Sub2 | Sub3 |  Sub4 |
1.  | ABC |   Eng  |  Maths| Science| Russian
2.  | FMC |    French| Null| Null   | Null
3.  | JBC |   French| Null | Null   | Null

我不确定如何实际做到这一点?我应该创建一个视图还是一个表?

我猜视图会很好。

4 个答案:

答案 0 :(得分:3)

我同意其他答案,GROUP_CONCAT和PHP一起分割逗号分隔值可能是最好的方法,但是如果由于任何其他原因你需要通过Pure SQL建议的输出我会建议一个以下任命。

<强> 1. Self Joins

SELECT  t1.Name, 
        MIN(t1.Subject) AS Sub1,
        MIN(t2.Subject) AS Sub2,
        MIN(t3.Subject) AS Sub3,
        MIN(t4.Subject) AS Sub4
FROM    Students t1
        LEFT JOIN Students T2 
            ON t1.Name = t2.Name 
            AND t2.Subject > t1.Subject
        LEFT JOIN Students T3 
            ON t2.Name = t3.Name 
            AND t3.Subject > t2.Subject
        LEFT JOIN Students T4 
            ON t3.Name = t4.Name 
            AND t4.Subject > t3.Subject
GROUP BY t1.Name;

<强> 2. Using a ROW_NUMBER Type function to aggregate

SELECT   Name,
         MAX(IF(RowNum = 1,Subject, NULL)) AS Sub1,
         MAX(IF(RowNum = 2,Subject, NULL)) AS Sub2,
         MAX(IF(RowNum = 3,Subject, NULL)) AS Sub3,
         MAX(IF(RowNum = 4,Subject, NULL)) AS Sub4
FROM     (    SELECT   Name,
                       Subject,
                       @r:= IF(@Name = Name, @r + 1, 1) AS RowNum,
                       @Name:= Name AS Name2
              FROM    Students,
                      (SELECT @Name:='') n,
                      (SELECT @r:= 0) r
              ORDER BY Name, Sno
          ) t
GROUP BY Name

答案 1 :(得分:1)

使用以下查询,获取姓名及其主题。

SELECT Name, GROUP_CONCAT(Subjects) AS List
FROM myTable
GROUP BY Name

然后在PHP中,您可以使用 implode 功能打印主题。

希望这有帮助。

Demo at sqlfiddle

答案 2 :(得分:0)

尝试使用GROUP BY和GROUP_CONCAT

SELECT Name, GROUP_CONCAT(Subjects) AS Subjects_list
FROM students_table
GROUP BY Name

然后在获取记录时使用PHP函数explode以获取存储在Subjects_list列中的不同值。

答案 3 :(得分:0)

它不漂亮!

要使用上述解决方案,您可以:

SELECT 
  Sno, 
  Name,
  NULLIF(SUBSTRING_INDEX(SUBSTRING_INDEX(all_subjects, ',', 1), ',', -1), '') AS Sub1,
  NULLIF(SUBSTRING_INDEX(SUBSTRING_INDEX(all_subjects, ',', 2), ',', -1), '') AS Sub2,
  NULLIF(SUBSTRING_INDEX(SUBSTRING_INDEX(all_subjects, ',', 3), ',', -1), '') AS Sub3,
  NULLIF(SUBSTRING_INDEX(SUBSTRING_INDEX(all_subjects, ',', 4), ',', -1), '') AS Sub4
FROM (
  SELECT Sno, Name, CONCAT(GROUP_CONCAT(Subjects ORDER BY Sno),',,,') AS all_subjects FROM table GROUP BY name
) inner_sel
;

您的要求会导致假设不能超过 4 科目。您还需要NULL s,其中没有提及四个科目。

有一些请求导致强制SQL代码,这通常是SQL的目的。

要解释上述内容:我们使用GROUP_CONCAT,然后再将其分解为碎片。由于可能会少于 4 元素,因此我们使用逗号(',,,')填充。然后我们根据它在连接字符串中的位置拆分每个部分,如果它是空的,则返回NULL

不能说这是我在漂亮方面更好的答案之一。我希望你觉得它很有用。