2

Im trying to get a pivot table with dynamic columns to work. When user_id is a string, it works fine but if its an int, then it seems to fail

Here is what I have so far with the assistance of past questions:

CREATE TABLE measure2
    (`inspection_date` date, `user_id` int, `score` int, comment text)
;

INSERT INTO measure2
    (`inspection_date`, `user_id`, `score`, comment)
VALUES
    ('2012-10-16', 0, 0, null),
    ('2012-10-16', 1, 0, null),
    ('2012-10-16', 2, 0, null),
    ('2012-10-16', 3, 0, null),
    ('2012-10-17', 0, 1, null),
    ('2012-10-17', 1, 1, null),
    ('2012-10-17', 2, 1, null),
    ('2012-10-18', 3, 1, null)
;


SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when user_id = ''',
      user_id,
      ''' then score end) AS ',
      user_id
    )
  ) INTO @sql
FROM  measure2;

SET @sql = CONCAT('SELECT inspection_date, ', @sql, '
                  FROM measure2
                  GROUP BY inspection_date');

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

see: http://sqlfiddle.com/#!2/eab24/1

Im sure its something simple, but what am I missing?

Thanks

2 Answers 2

2

Since the values are in int you are are making them the column names, you have to wrap the values in a backtick

The sql will look like:

max(case when user_id = 1 then score end) as `1`

The full query will be:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when user_id = ''',
      user_id,
      ''' then score end) AS `',
      user_id, '`'
    )
  ) INTO @sql
FROM  measure2;

SET @sql = CONCAT('SELECT inspection_date, ', @sql, ' 
                  FROM measure2 
                  GROUP BY inspection_date');

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

See SQL Fiddle with Demo

Sign up to request clarification or add additional context in comments.

1 Comment

hello sir, As I Am digging some dynamic pivot table, this caught my attention.. and I want to know How this query works in php or how I could do this query in php
1

Simple indeed - numbers alone aren't valid column names in SQL, so you need to amend your code to enclose them in backticks:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when user_id = ',
      user_id,
      ' then score end) AS `',
      user_id,
      '`'
    )
  ) INTO @sql
FROM  measure2;

SET @sql = CONCAT('SELECT inspection_date, ', @sql, ' 
                  FROM measure2 
                  GROUP BY inspection_date');

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

I suggest retaining this change for string values as well, in case some of your string values match reserved words or include spaces.

(Also, ' aren't required around numeric values, so I have removed them from the case clauses.)

SQLFiddle here.

1 Comment

Thanks as well! You and bluefeet must have posted at almost the exact same time!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.