0

I have an SQL table setup similar to this:

name   |  subject |
-------+----------+
Harry  | Painting |
Sandra | Soccer   | 
Sandra | English  |

How can I write a select statement that merges the rows if they have multiple subject, so it would output a result like this:

name   |  subject 1 |  subject 2 |
-------+------------+------------+
Harry  | Painting   |            |
Sandra | Soccer     |   English  |
John Woo
  • 258,903
  • 69
  • 498
  • 492
user2562674
  • 41
  • 1
  • 2
  • 7

4 Answers4

0

You shouldn't. The best approach is to join the tables so you have:

  • Harry, Painting
  • Sandra, Soccer
  • Sandra, English

And then process these rows in your scripting language (PHP etc) to turn it into the hierarchical data structure you desire

In your example above, what would happen when there's 3 subjects per person, 10, 100, etc.

SQL only really works with two dimensional data. For three dimensions you either need to pre/post process as i've suggested, or move to something like NoSQL mongoDB that deals with structured objects instead of table rows.

ricick
  • 5,694
  • 3
  • 25
  • 37
0

Since you mentioned that the maximum number of subjects is only 2, you can therefore, generate a sequential number for each name and used that to pivot the columns.

SELECT  Name,
        MAX(CASE WHEN rn = 1 THEN Subject END) Subject1,
        MAX(CASE WHEN rn = 2 THEN Subject END) Subject2
FROM
(
    SELECT  A.name, 
            A.subject, 
            (
                SELECT  COUNT(*)
                FROM    tableName c
                WHERE   c.name = a.name AND
                        c.subject <= a.subject) AS rn
    FROM    TableName a
) aa
GROUP BY Name

The above is an SQL way.

John Woo
  • 258,903
  • 69
  • 498
  • 492
0

You need a PIVOT routine. Serach for this in the engine of your choice.

Some RDBMSs have this built in. There is an alternative using a CASE statement in the SELECT clause, for which there are many blog posts out there.

Michael Green
  • 1,397
  • 1
  • 17
  • 25
0

You can accomplish this in one statement using a combination of substring_index() and group_concat() like this (SQLfiddle)

SELECT DISTINCT s.name, 
       substring_index(p.subject_list, ',', 1) AS "subject_1",
       IF(instr(p.subject_list, ','), 
          substring_index(p.subject_list, ',', -1), 
          NULL
       ) AS "subject_2"
  FROM subjects s
  JOIN (SELECT name, GROUP_CONCAT(subject) AS "subject_list"
          FROM subjects
         GROUP BY name
       ) p on p.name = s.name
;
ob1quixote
  • 399
  • 1
  • 3
  • 8