2013-10-01 64 views
1

我正在研究班次排班解決方案,需要您的幫助。 數據庫佈局看起來是這樣的:database-layoutmySQL複雜連接,甚至數據樞軸

我的查詢來獲取所有計劃一個月是這樣的:

SELECT 
    ca.date, 
    ss.num, 
    ma.name 
FROM dp_dienstplan AS dp 
JOIN ma_mitarbeiter AS ma ON ma.id=dp.dp_mitarbeiter_id 
JOIN ss_schienen AS ss ON ss.id=dp.dp_schienen_id 
JOIN sc_schicht  AS sc ON sc.id=ss.ss_schicht_id 
RIGHT JOIN calendar AS ca ON ca.date=dp.dp_datum 
WHERE 
    month(ca.date)=9 AND year(ca.date)=2013 

日曆表是一個輔助表的日期在未來幾年得到在沒有任何計劃待決的結果中甚至有幾天。

查詢的結果是這樣的:

date  |num  |name 
---------------------------- 
2013-09-01 NULL  NULL 
2013-09-02 2   foo 
2013-09-02 3   bar 
2013-09-03 2   uncle 
2013-09-03 1   mac 
2013-09-03 7   super 
2013-09-04 NULL  NULL 
2013-09-04 2   master 
. 
. 
. 
2013-09-30 NULL  NULL 

什麼,我做夢看起來像這樣的結果:

date  |1num |1name |2num |2name |3num |3name. . .|7name|7num 
----------------------------------------------------------------- 
2013-09-01 NULL NULL NULL NULL NULL NULL . . . NULL NULL 
2013-09-02 NULL NULL 2  foo 3  bar . . . NULL NULL 
2013-09-03 1  mac 2  uncle NULL NULL . . . 7  super 
2013-09-04 NULL NULL 2  master NULL NULL . . . NULL NULL 
.   .  .  .  .  .  .   .  . 
.   .  .  .  .  .  .   .  . 
.   .  .  .  .  .  .   .  . 
2013-09-30 NULL NULL NULL NULL NULL NULL . . . NULL NULL 

應該有每一天一列,名稱並按照'num'值的順序。 我希望你明白我在說什麼,對不起我的英語。

我有另一個助手錶,其中包含從1到200的值,我試圖正確加入,但我沒有成功。

在此先感謝,抱歉,如果這是一個重複的問題,我沒有找到任何結果,谷歌或在論壇上,也許是因爲我不知道要搜索什麼。

乾杯,拉爾夫。

+0

預先知道所有的數字'num'嗎? – peterm

回答

0

首先不適用於您用於篩選WHERE子句中的數據的列。它可以防止MySQL使用該列上可能有的任何索引,從而有效地導致表上的全掃描。話雖這麼說,而不是

WHERE month(ca.date)=9 AND year(ca.date)=2013 

你最好做類似

WHERE ca.date BETWEEN '2013-09-01' AND LAST_DAY('2013-09-01') 

,並確保您有calendar.datedp_dienstplan.dp_datum指數。


現在如果ss.num所有值已知前期可以通過在靜態查詢使用條件聚合得到你的支點

SELECT ca.date, 
     MAX(CASE WHEN ss.num = 1 THEN ss.num END) `1num`, 
     MAX(CASE WHEN ss.num = 1 THEN ss.name END) `1name`, 
     MAX(CASE WHEN ss.num = 2 THEN ss.num END) `2num`, 
     MAX(CASE WHEN ss.num = 2 THEN ss.name END) `2name`, 
     MAX(CASE WHEN ss.num = 3 THEN ss.num END) `3num`, 
     MAX(CASE WHEN ss.num = 3 THEN ss.name END) `3name`, 
     MAX(CASE WHEN ss.num = 4 THEN ss.num END) `4num`, 
     MAX(CASE WHEN ss.num = 4 THEN ss.name END) `4name`, 
     MAX(CASE WHEN ss.num = 5 THEN ss.num END) `5num`, 
     MAX(CASE WHEN ss.num = 5 THEN ss.name END) `5name`, 
     MAX(CASE WHEN ss.num = 6 THEN ss.num END) `6num`, 
     MAX(CASE WHEN ss.num = 6 THEN ss.name END) `6name`, 
     MAX(CASE WHEN ss.num = 7 THEN ss.num END) `7num`, 
     MAX(CASE WHEN ss.num = 7 THEN ss.name END) `7name` 
    FROM dp_dienstplan AS dp 
    JOIN ma_mitarbeiter AS ma ON ma.id=dp.dp_mitarbeiter_id 
    JOIN ss_schienen AS ss ON ss.id=dp.dp_schienen_id 
    JOIN sc_schicht  AS sc ON sc.id=ss.ss_schicht_id 
    RIGHT JOIN calendar AS ca ON ca.date=dp.dp_datum 
WHERE ca.date BETWEEN '2013-09-01' AND LAST_DAY('2013-09-01') 
GROUP BY ca.date 

輸出:

 
|  DATE | 1NUM | 1NAME | 2NUM | 2NAME | 3NUM | 3NAME | 4NUM | 4NAME | 5NUM | 5NAME | 6NUM | 6NAME | 7NUM | 7NAME | 
|------------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------| 
| 2013-09-01 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | 
| 2013-09-02 | (null) | (null) |  2 | foo |  3 | bar | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | 
| 2013-09-03 |  1 | mac |  2 | uncle | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) |  7 | super | 
| 2013-09-04 | (null) | (null) |  2 | master | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | 
| 2013-09-30 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | 

這裏是SQLFiddle demo 在本演示中,你的連接表是由一個包含你作爲查詢結果顯示的樣本數據的表來模擬的

+0

彼得你好!非常感謝您的回答和建議!列的名稱並不重要。我把它們拿到一個數組中,然後JSON被處理成'handontable',它處理我的編輯。問題是,'num'的值是動態的,它們的範圍在約。 7和70.所以這個數字不同於請求和請求。截至目前,我嘗試通過php-loop動態創建sql語句。如果你有不同的建議,你真的很歡迎:-)謝謝! –