2016-07-06 17 views
1

Ich versuche, eine dynamische Pivot-Tabelle mit einer MySQL Prepared-Anweisung zu erstellen, die ich aus den zahlreichen anderen Fragen zu MySQL-Pivot-Tabellen zusammengestellt habe. Aber ich bekomme nicht die Ausgabe, die ich erwarte.MySQL - Dynamische Pivot-Tabelle Gruppierung Problem

Meine Tabellen wie folgt aussehen:

Fähigkeiten jede „Fähigkeit“ enthält, dass ein Mitarbeiter auf

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

employee_skills enthält, die Mitarbeiter geschult wurde ein Protokoll über den Zeitpunkt ausgebildet werden könnten auf einer Fähigkeit

| 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 enthält Fähigkeiten, die einer "Kampagne" zugewiesen wurden.

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

Ich habe auch eine Tabelle Mitarbeiterdaten enthält (first_name, last_name etc.) mit employee_id als Primärschlüssel.


gewünschte Ergebnis

Dies ist, was ich in meiner Ansicht angezeigt werden müssen:

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

Wo die Daten gezeigt, sollte die jüngstenemployee_skills.date_trained sein.

Ich brauche auch die Fähigkeit, ein Datum if (employee_skills.date_trained < skills.expiry_date) zu kennzeichnen. Aber ich kann das später herausfinden.


Meine Suche

ich eine gespeicherte Prozedur geschrieben haben, die als Parameter campaign_id nimmt. Ich glaube, ich fast da bin, aber ich bin nicht das Ergebnis bekomme ich erwarte mich ...

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; 

Welche Ausgabe so etwas wie dies:

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

Obwohl ich bin mit einem GROUP. Ich war eine Weile hier fest, vielleicht kann mir jemand meinen Fehler sagen?

SQL FIDDLE:

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 

Ergebnis ist eine Pivot-Tabelle wie folgt aus:: http://sqlfiddle.com/#!9/7caa6c/1

+0

Versuchen Sie, 'JOIN campaign_skills cs ON cs.skill_id = s.id WHERE cs.campaign_id = campaignID 'zu entfernen, wenn dynamic sql generiert wird. – Blank

+0

Wenn ich diese Zeilen herausnehme, habe ich immer noch das gleiche Problem. Der einzige Unterschied ist, dass ich jede Fähigkeit bekomme, anstatt nur nach 'campaign_id' gefiltert zu werden. – DinosaurHunter

+0

sqlfiddle und ich werde es versuchen – Drew

Antwort

1

Die folgende SQL kann zur Lösung des Problems ein Ausgangspunkt sein

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

Wenn SQL dynamisch erstellt, können die Skill-IDs durch den Fertigkeitsnamen ersetzt werden. Es ist auch möglich, die IDs nachträglich zu ersetzen.

+0

Akzeptiert dies als die Antwort - alles, was ich tun musste, war hinzufügen 'MAX()' herum die "CASE" -Aussagen; 'MAX (FALL WENN ... ENDE)'. Dies bedeutete, dass ich nur durch die employee_id gruppieren konnte und das Ergebnis produzieren konnte, nach dem ich suchte. – DinosaurHunter