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
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
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
sqlfiddle und ich werde es versuchen – Drew