mnfst
mnfst

Reputation: 71

how to display data in mysql like pivot in excel

I have query like this:

SELECT DATE,REGION,COUNT(*)
FROM ALL_ID_DATA
WHERE DATE in (SUBDATE(CURDATE(),1),SUBDATE(CURDATE(),2),SUBDATE(CURDATE(),8))
AND DIRECTION='inbound'
AND REASON_1 = 'complaint'
GROUP BY REGION,DATE DESC

and the result is capture What is the right query to display like this capture below

result Could somebody help me?

Upvotes: 2

Views: 1380

Answers (2)

Taryn
Taryn

Reputation: 247710

This type of query is known as a PIVOT. Unfortunately, MySQL doesn't have a PIVOT function, so you will need to replicate the function using a CASE statement and an aggregate function.

If you know the number of columns to transform, then you can hard-code the values:

select region,
  SUM(CASE WHEN date = '2012-09-24' THEN 1 END) as `2012-09-24`,
  SUM(CASE WHEN date = '2012-09-30' THEN 1 END) as `2012-09-30`,
  SUM(CASE WHEN date = '2012-10-01' THEN 1 END) as `2012-10-01`
from ALL_ID_DATA
group by region;

select region,
  COUNT(CASE WHEN date = '2012-09-24' THEN 1 ELSE null END) as `2012-09-24`,
  COUNT(CASE WHEN date = '2012-09-30' THEN 1 ELSE null END) as `2012-09-30`,
  COUNT(CASE WHEN date = '2012-10-01' THEN 1 ELSE null END) as `2012-10-01`
from ALL_ID_DATA
group by region;

See SQL Fiddle with Demo.

Then adding this to your existing query, it would be:

SELECT REGION,
  SUM(CASE WHEN date = '2012-09-24' THEN 1 END) as `2012-09-24`,
  SUM(CASE WHEN date = '2012-09-30' THEN 1 END) as `2012-09-30`,
  SUM(CASE WHEN date = '2012-10-01' THEN 1 END) as `2012-10-01`
FROM ALL_ID_DATA
WHERE DATE in (SUBDATE(CURDATE(),1),SUBDATE(CURDATE(),2),SUBDATE(CURDATE(),8))
  AND DIRECTION='inbound'
  AND REASON_1 = 'complaint'
GROUP BY REGION

OR

SELECT REGION,
  COUNT(CASE WHEN date = '2012-09-24' THEN 1 ELSE null END) as `2012-09-24`,
  COUNT(CASE WHEN date = '2012-09-30' THEN 1 ELSE null END) as `2012-09-30`,
  COUNT(CASE WHEN date = '2012-10-01' THEN 1 ELSE null END) as `2012-10-01`
FROM ALL_ID_DATA
WHERE DATE in (SUBDATE(CURDATE(),1),SUBDATE(CURDATE(),2),SUBDATE(CURDATE(),8))
  AND DIRECTION='inbound'
  AND REASON_1 = 'complaint'
GROUP BY REGION

Now if you have an unknown number of dates to transform into columns, then you can use prepared statements and your query would be similar to this (See SQL Fiddle with Demo):

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'sum(case when date = ''',
      date,
      ''' then 1 else 0 end) AS ''',
      Date(date), ''''
    )
  ) INTO @sql
FROM ALL_ID_DATA;

select @sql;

SET @sql = CONCAT('SELECT region, ', @sql, ' 
                   FROM ALL_ID_DATA
                   GROUP BY region');

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

Then placing your original query in the prepared statement the final query would be:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'sum(case when date = ''',
      date,
      ''' then 1 else 0 end) AS ''',
      Date(date), ''''
    )
  ) INTO @sql
FROM ALL_ID_DATA;

select @sql;

SET @sql = CONCAT('SELECT region, ', @sql, ' 
                   FROM ALL_ID_DATA
                   WHERE DATE in (SUBDATE(CURDATE(),1),SUBDATE(CURDATE(),2),SUBDATE(CURDATE(),8))
                   AND DIRECTION=''inbound''
                   AND REASON_1 = ''complaint''');

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

Upvotes: 4

User404
User404

Reputation: 2192

I think you are looking for this : http://www.artfulsoftware.com/infotree/queries.php#78

Upvotes: 1

Related Questions