0

I have data in Mysql in this format :

   name sub
----------------
    a   maths
    a   science
    a   history
    b   maths
    b   science
    a   computer
    a   english
    c   computer
    c   history
    b   history
    c   maths

I am planning to display this data in this format in HTML:

Name    maths   science history computer  english
a          y        y       y       y         y
b          y        y       y       n         n
c          y        n       y       y         n

How to formulate my sql query other than pivot table method?

qwww
  • 1,313
  • 4
  • 22
  • 48
  • You mention html. Presumably, you have some layer that transcribes the raw data to html. If it was me I'd handle the logic of missing results, and tabulation, there. – Strawberry Aug 28 '18 at 16:47

3 Answers3

1

If you want to dynamically create column, you can use dynamic pivot.

use GROUP_CONCAT to create your pivot column, then Concat the SQL execute syntax, execute it dynamically.

SET @sql = NULL;

SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'COALESCE(MAX(CASE WHEN sub = ''',
      sub,
      ''' then ''y'' end),''n'') AS ',
      sub
    )
  ) INTO @sql
FROM T;

SET @sql = CONCAT('SELECT name, ', @sql, ' 
                  FROM T 
                  GROUP BY name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

sqlfiddle

Result

   name   maths science history computer    english
    a       y       y       y     y          y
    b       y       y       y     n          n
    c       y       n       y     y          n
D-Shih
  • 44,943
  • 6
  • 31
  • 51
1

I found a similar case here. Let me brief a little bit of the problem and solution:

Problem:

Convert this:

select * from history;

+--------+----------+-----------+
| hostid | itemname | itemvalue |
+--------+----------+-----------+
|      1 | A        |        10 |
|      1 | B        |         3 |
|      2 | A        |         9 |
|      2 | C        |        40 |
+--------+----------+-----------+

Into this:

select * from history_itemvalue_pivot;

+--------+------+------+------+
| hostid | A    | B    | C    |
+--------+------+------+------+
|      1 |   10 |    3 |    0 |
|      2 |    9 |    0 |   40 |
+--------+------+------+------+

Solution:

From the article, here are the steps the author did:

  1. select the columns of interest, i.e. y-values and x-values
  2. extend the base table with extra columns -- one for each x-value
  3. group and aggregate the extended table -- one group for each y-value
  4. (optional) prettify the aggregated table

Here is the full article: MySQL - Rows to Columns

Hope it helps.

Regards,

0

You can use condition aggregation in SQL :

SELECT name,  
       MAX(CASE WHEN sub = 'maths'   then 'y' ELSE 'n' END) AS maths,
       MAX(CASE WHEN sub = 'science' then 'y' ELSE 'n' END) AS science,
       MAX(CASE WHEN sub = 'history' then 'y' ELSE 'n' END) AS history,
       MAX(CASE WHEN sub = 'computer'then 'y' ELSE 'n' END) AS computer,
       MAX(CASE WHEN sub = 'english' then 'y' ELSE 'n' END) AS english
FROM table t
GROUP BY name;
Yogesh Sharma
  • 49,870
  • 5
  • 26
  • 52