2016-07-06 4 views
1

Я пытаюсь создать динамическую сводную таблицу с использованием подготовленного MySQL заявления. Я собрал множество других вопросов о таблицах MySQL. Но я не получаю вывод, которого я ожидаю.MySQL - динамическая сводная таблица группировки Проблема

Мои таблицы выглядеть следующим образом:

навыки содержит все «мастерство», что работник может обучаться на

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

employee_skills содержит журнал о дате, которая была обученного сотрудника по искусству

| 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 содержит умение, которое было присвоено «кампании».

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

У меня есть таблица, содержащая детали сотрудника (first_name, last_name и т.д.) с employee_id в качестве первичного ключа.


желаемого результата

Это то, что мне нужно, чтобы отобразить на мой взгляд:

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

Где даты должен показываться последнийemployee_skills.date_trained.

Мне также понадобится указать дату if (employee_skills.date_trained < skills.expiry_date). Но я могу понять это позже.


Мой запрос

Я написал хранимую процедуру, которая принимает CAMPAIGN_ID в качестве параметра. Я думаю, что я почти там, но я не получаю результат я ожидал ...

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; 

Какой будет выводить что-то вроде этого:

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

Даже если я с помощью GROUP. Я застрял на этом какое-то время, поэтому, может быть, кто-то может сказать мне свою ошибку?

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

+0

Попробуйте удалить 'JOIN campaign_skills cs ON cs.skill_id = s.id WHERE cs.campaign_id = campaignID' при генерации динамического sql. – Blank

+0

Если я возьму эти строки, у меня все еще будет такая же проблема. Единственное различие заключается в том, что я получаю каждое умение вместо того, чтобы просто фильтроваться с помощью 'campaign_id'. – DinosaurHunter

+0

sqlfiddle, и я попробую его – Drew

ответ

1

Следующая SQL может быть отправной точкой для решения этой проблемы:

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 

Результат является сводной таблицы, как это:

| 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)  | 

Если SQL является динамически создаваемые идентификаторы навыков могут быть заменены именем навыка. Также после этого можно заменить идентификаторы.

+0

Принял это как ответ - все, что мне нужно было сделать, это добавить 'MAX()' around операторы 'CASE'; 'MAX (CASE WHEN ... END)'. Это означало, что я мог бы группировать только employee_id и приводить результат, который я получил. – DinosaurHunter

Смежные вопросы