MySQL - Dynamic Pivot Table Grouping Issue

纵然是瞬间 提交于 2019-12-24 17:22:53

问题


I'm trying to create a dynamic pivot table using a MySQL Prepared Statement I've put together from the numerous other questions about MySQL pivot tables. But I'm not getting the output I'm expecting.

My tables look like this:

skills contains every "skill" that an employee could be trained on

| id | skill   | expiry_date |
 ----+---------+-------------
| 1  | SkillA  | 2016-07-01  |
| 2  | SkillB  | 2016-06-01  |
| 3  | SkillC  | 2016-04-01  |

employee_skills contains a log of the date which an employee was trained on a skill

| id | employee_id | skill_id | date_trained |
 ----+-------------+----------+--------------
| 1  | 1000001     | 1        | 2016-05-01   |
| 2  | 1000002     | 1        | 2016-05-02   |
| 3  | 1000001     | 2        | 2016-05-03   |
| 4  | 1000002     | 3        | 2016-05-04   |

campaign_skills contains skill which ahve been assigned to a "campaign".

| id | campaign_id | skill_id |
 ----+-------------+----------
| 1  | 1001        | 1        |
| 2  | 1001        | 3        |
| 3  | 1002        | 2        |

I also have a table containing employee details (first_name, last_name etc.) with employee_id as the Primary Key.


Desired Outcome

This is what I need to display in my view:

| Employee    | SkillA     | SkillB      | SkillC      |
 -------------+------------+-------------+-------------
| Person One  | 2016-05-01 | 2016-05-03  | -           | 
| Person Two  | 2016-05-02 | -           | 2016-05-04  |

Where the dates shown should be the most recent employee_skills.date_trained.

I will also need the ability to flag a date if ( employee_skills.date_trained < skills.expiry_date ). But I can figure that one out later.


My Query

I've written a stored procedure which takes campaign_id as a parameter. I think I'm nearly there but I'm not getting the result I'm expecting...

SET @sql = NULL;

SELECT 
    GROUP_CONCAT(DISTINCT
        CONCAT(
            'CASE WHEN skill = ''',
            s.skill,
            ''' THEN es.date_trained ELSE 0 END AS ',
            s.skill
        )
    ) INTO @sql
FROM  skills s
JOIN  campaign_skills cs ON cs.skill_id = s.id
WHERE cs.campaign_id = campaignID;

SET @sql = CONCAT('

    SELECT    CONCAT(e.first_name, " ", e.last_name) AS employee, ', @sql, ' 
    FROM      employees e
    LEFT JOIN employee_skills es ON es.employee_id = e.id
    LEFT JOIN campaign_skills cs ON cs.skill_id = es.skill_id
    LEFT JOIN skills s ON s.id = es.skill_id

    WHERE e.id IN (SELECT id FROM employees WHERE campaign_id = campaignID) 
        AND e.active = 1

    ORDER BY es.id DESC
    GROUP BY e.id, s.id

');

PREPARE statement FROM @sql;
EXECUTE statement;
DEALLOCATE PREPARE statement;

Which will output something like this:

| employee   | SkillA     | SkillB     |
 ------------+------------+------------
| Person One | 2015-05-04 | -          |
| Person One | -          | 2016-05-01 |
| Person Two | -          | 2016-03-25 |
| Person Two | 2016-04-04 | -          |

Even though I'm using a GROUP. I've been stuck on this for a while so maybe someone can tell me my mistake?

SQL FIDDLE: http://sqlfiddle.com/#!9/7caa6c/1


回答1:


The following SQL can be a starting point for solving the problem:

SELECT
  es.employee_id,
  CONCAT(e.first_name, " ", e.last_name) AS employee,
  MAX(IF (es.skill_id = 1, es.date_trained, null)) AS '1',
  MAX(IF (es.skill_id = 2, es.date_trained, null)) AS '2',
  MAX(IF (es.skill_id = 3, es.date_trained, null)) AS '3'
FROM
  employee_skills es
  LEFT JOIN employees e ON es.employee_id = e.id
GROUP BY
  es.employee_id 

Result is a pivot table like this:

| employee_id | employee   | 1          | 2          | 3          |
+-------------+------------+------------+------------+------------+
| 1001675     | Person Two | (null)     | 2016-07-02 | 2016-07-04 |
| 1006111     | Person One | 2016-07-01 | 2016-07-11 | (null)     |

If SQL is created dynamically the skill IDs can be replaced by the skill name. Also it is possible to replace the IDs afterwards.



来源:https://stackoverflow.com/questions/38218685/mysql-dynamic-pivot-table-grouping-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!