简体   繁体   中英

MySQL pivoting with VARCHAR

Let say I have the table 'Organization' with two columns 'Name' and 'Role'. The field 'Name' contains a string, similarly 'Role' can be a string in the following list: ['Admin', 'Moderator', 'User'].

I would like to perform a query that prints me the users sorted by roles. For instance, having the following starting table:

+++++++++++++++++++++++
+   Name   +   Role   +
+++++++++++++++++++++++
+   Sara   +   User   +
+   Tony   +   Admin  +
+   John   +   User   +
+++++++++++++++++++++++

I would like to obtain the following query:

++++++++++++++++++++++++++++++++++++++++
+   Admin   +   Moderator   +   User   +
++++++++++++++++++++++++++++++++++++++++
+   Tony    +      NULL     +   Sara   +
+   NULL    +      NULL     +   John   +
++++++++++++++++++++++++++++++++++++++++

The best solution I came up so far is the following, but I would like to have a more compact solution. What I need is to separate the columns and then rejoin them, but I do not know how to do this...

SELECT CASE WHEN Role = 'Admin' THEN Name END AS 'Admin', 
CASE WHEN Role = 'Moderator' THEN Name END AS 'Moderator', 
CASE WHEN Role= 'User' THEN Name END AS 'User'
FROM Organization;

++++++++++++++++++++++++++++++++++++++++
+   Admin   +   Moderator   +   User   +
++++++++++++++++++++++++++++++++++++++++
+   NULL    +      NULL     +   Sara   +
+   Tony    +      NULL     +   NULL   +
+   NULL    +      NULL     +   John   +
++++++++++++++++++++++++++++++++++++++++

To do this you can use equivalent of ROW_NUMBER and GROUP BY calculated RowNumber column:

SELECT 
    MAX(CASE WHEN Role = 'Admin' THEN Name END) AS `Admin`, 
    MAX(CASE WHEN Role = 'Moderator' THEN Name END) AS `Moderator`, 
    MAX(CASE WHEN Role = 'User' THEN Name END) AS `User`
FROM (
      SELECT *
        ,@row_num := IF(@prev_value=concat_ws('',t.Role),@row_num+1,1) AS RowNumber
        ,@prev_value := concat_ws('',t.Role)  
      FROM Organization t,
         (SELECT @row_num := 1) x,
         (SELECT @prev_value := '') y
      ORDER BY t.Role   
     ) AS sub
GROUP BY RowNumber

SqlFiddleDemo

Output:

╔═════════╦════════════╦══════╗
║ Admin   ║ Moderator  ║ User ║
╠═════════╬════════════╬══════╣
║ Tony    ║ (null)     ║ Sara ║
║ (null)  ║ (null)     ║ John ║
╚═════════╩════════════╩══════╝

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM