2016-07-06 57 views
1

我正在嘗試使用MySQL Prepared Statement創建一個動態數據透視表,我已經從許多關於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_namelast_name等)employee_id作爲主鍵的表。


期望的結果

這是我需要在我視圖中顯示:如果顯示的日期應該是最近employee_skills.date_trained

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

我還需要能夠標記日期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是動態創建的技能ID可以由技能名稱替換。之後也可以替換ID。

+0

接受這個答案 - 我所要做的就是添加MAX() 'CASE'語句; 'MAX(CASE WHEN ... END)'。這意味着我只能通過employee_id進行分組,併產生我之後的結果。 – DinosaurHunter