Kamil Grabowski
Kamil Grabowski

Reputation: 33

Pivot table from MySQL

I'm newbie in MySQL i want create pivot table by mysql table like this:

My table:

*------------*-------*----------------*-------*------------*
|    Name    | Place |  Kind of work  | Hours |    Date    |
*------------*-------*----------------*-------*------------*
| Test Test  |  abc  |      abc       |   5   | 2020-01-20 |
| Test1 Test1|  abc  |      abc       |   6   | 2020-01-21 |
| Test2 Test2|  abc  |      abc       |   7   | 2020-01-21 |
| Test Test  |  abc  |      abc       |   5   | 2020-01-23 |
| Test1 Test1|  abc  |      abc       |   6   | 2020-01-24 |
| Test2 Test2|  abc  |      abc       |   7   | 2020-01-25 |
*------------*-------*----------------*-------*------------*

I want to get this by mysql select (if it is possible)

*---------------------*------------*------------*------------*------------*------------*
| Name (group by name)| 2020-01-20 | 2020-01-21 | 2020-01-23 | 2020-01-24 | 2020-01-25 |
*---------------------*------------*------------*------------*------------*------------*
| Test Test           |     5      |            |      5     |            |            |
| Test1 Test1         |            |      6     |            |     6      |            |
| Test2 Test2         |            |      7     |            |            |      7     |
*---------------------*------------*------------*------------*------------*------------*

Thanks for help :)

Upvotes: 1

Views: 217

Answers (3)

Kamil Grabowski
Kamil Grabowski

Reputation: 33

So... it's not possible to execute this stmt on big table:

SET SESSION group_concat_max_len =20000; SET @sql = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT( 'MAX(IF(datapracy = "', datapracy, '" , liczbagodzin, NULL)) AS "', datapracy, '"' ) ) INTO @sql FROM STYCZEN2020PF1; SET @sql = CONCAT("create view STYCZEN2020PF2 as SELECT nowakolumna, ", @sql, " FROM STYCZEN2020PF1 GROUP BY nowakolumna"); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;

We need creat view of month first:

Create or replace view STYCZEN2020PF1 AS Select t2.nowakolumna, t1.datapracy, sum(t1.liczbagodzin) as liczbagodzin from wp_wpdatatable_5 as t2, wp_wpdatatable_1_1 ast1where t2.wdt_ID= t1.imieinazwiskopracownikaAND t1.datapracy BETWEEN '2020-01-01' AND '2020-01-31' group by t1.datapracy, t2.nowakolumna HAVING COUNT(*)

And after create second pivot view from first stmt. This is solution. In the end we should select * from view.

Big thanks for help.

Upvotes: 1

Kamil Grabowski
Kamil Grabowski

Reputation: 33

I found solution this is code for my native table:

SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(datapracy = "', datapracy, '" , liczbagodzin, NULL)) AS "', datapracy, '"'
)
) INTO @sql
FROM wp_wpdatatable_1_1 WHERE datapracy BETWEEN '2020-01-01' AND '2020-01-31';

SET @sql = CONCAT("SELECT imieinazwiskopracownika, ", @sql, " FROM wp_wpdatatable_1_1 GROUP BY imieinazwiskopracownika");

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

But now i have question how create from this stmt mysql view?

Upvotes: 1

Gosfly
Gosfly

Reputation: 1300

This is a pretty nice question as there is no pivot functions in MySQL. Moreover, you seem to need a dynamic number of columns which makes it a bit more difficult than a fixed and pre-determined number of columns.

The only way i know to achieve such a pivot in MySQL is to use a prepared statement as below :

SET @sql = NULL;

SELECT
     GROUP_CONCAT(DISTINCT
          CONCAT(
               'MAX(IF(date = ''',
               date,
               ''', hours, NULL)) AS "',
               date,'"'
          )
     ) INTO @sql
FROM test;

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

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

SEE FULL DEMO HERE

Upvotes: 0

Related Questions