2014-03-14 17 views
1

我覺得這是超越我,我想我的MySQL查詢轉換,以便它顯示正是這樣的行和列: enter image description herePHP和MySQL查詢,使用PHP行轉換爲列

這是我有一個MySQL查詢創建: enter image description here

下面是實際的查詢來創建此:

SELECT h.workdate AS `Date` 
, DAYNAME(h.workdate) AS `Day` 
, COALESCE(TRUNCATE(SUM(
    CASE 
    WHEN (shift='AM' AND DriverDock = 'Driv' AND `Salary Code Description` LIKE '%Perm%') 
     THEN 
     CASE 
     WHEN paycode IN ('03 Overtime 2.0') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 2.0) 
     WHEN paycode IN ('02 Overtime 1.5') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 1.5) 
     WHEN paycode IN ('01 Ordinary') 
      THEN (employeehours * p.`Base Rate`) 
     END 
    END 
    ),2),0) AS `AMPERMDRIV` 
, COALESCE(TRUNCATE(SUM(
    CASE 
    WHEN (shift='AM' AND DriverDock = 'Dock' AND `Salary Code Description` LIKE '%Perm%') 
     THEN 
     CASE 
     WHEN paycode IN ('03 Overtime 2.0') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 2.0) 
     WHEN paycode IN ('02 Overtime 1.5') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 1.5) 
     WHEN paycode IN ('01 Ordinary') 
      THEN (employeehours * p.`Base Rate`) 
     END 
    END 
    ),2),0) AS `AMPERMDOCK` 
    , COALESCE(TRUNCATE(SUM(
    CASE 
    WHEN (shift='AM' AND DriverDock = 'Driv' AND `Salary Code Description` LIKE '%Cas%') 
     THEN 
     CASE 
     WHEN paycode IN ('03 Overtime 2.0') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 2.0) 
     WHEN paycode IN ('02 Overtime 1.5') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 1.5) 
     WHEN paycode IN ('01 Ordinary') 
      THEN (employeehours * p.`Base Rate`) 
     END 
    END 
    ),2),0) AS `AMCASUDRIV` 
, COALESCE(TRUNCATE(SUM(
    CASE 
    WHEN (shift='AM' AND DriverDock = 'Dock' AND `Salary Code Description` LIKE '%Cas%') 
     THEN 
     CASE 
     WHEN paycode IN ('03 Overtime 2.0') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 2.0) 
     WHEN paycode IN ('02 Overtime 1.5') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 1.5) 
     WHEN paycode IN ('01 Ordinary') 
      THEN (employeehours * p.`Base Rate`) 
     END 
    END 
    ),2),0) AS `AMCASUDOCK` 
, COALESCE(TRUNCATE(SUM(
    CASE 
    WHEN (shift='AM' AND DriverDock = 'Driv' AND `Salary Code Description` LIKE '%AGENT%') 
     THEN 
     CASE 
     WHEN paycode IN ('03 Overtime 2.0') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 2.0) 
     WHEN paycode IN ('02 Overtime 1.5') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 1.5) 
     WHEN paycode IN ('01 Ordinary') 
      THEN (employeehours * p.`Base Rate`) 
     END 
    END 
    ),2),0) AS `AMAGENTDRIV` 
, COALESCE(TRUNCATE(SUM(
    CASE 
    WHEN (shift='AM' AND DriverDock = 'Dock' AND `Salary Code Description` LIKE '%AGENT%') 
     THEN 
     CASE 
     WHEN paycode IN ('03 Overtime 2.0') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 2.0) 
     WHEN paycode IN ('02 Overtime 1.5') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 1.5) 
     WHEN paycode IN ('01 Ordinary') 
      THEN (employeehours * p.`Base Rate`) 
     END 
    END 
    ),2),0) AS `AMAGENTDOCK` 
, COALESCE(TRUNCATE(SUM(
    CASE 
    WHEN (shift='PM' AND DriverDock = 'Driv' AND `Salary Code Description` LIKE '%Perm%') 
     THEN 
     CASE 
     WHEN paycode IN ('03 Overtime 2.0') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 2.0) 
     WHEN paycode IN ('02 Overtime 1.5') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 1.5) 
     WHEN paycode IN ('01 Ordinary') 
      THEN (employeehours * p.`Base Rate`) 
     END 
    END 
    ),2),0) AS `PMPERMDRIV` 
, COALESCE(TRUNCATE(SUM(
    CASE 
    WHEN (shift='PM' AND DriverDock = 'Dock' AND `Salary Code Description` LIKE '%Perm%') 
     THEN 
     CASE 
     WHEN paycode IN ('03 Overtime 2.0') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 2.0) 
     WHEN paycode IN ('02 Overtime 1.5') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 1.5) 
     WHEN paycode IN ('01 Ordinary') 
      THEN (employeehours * p.`Base Rate`) 
     END 
    END 
    ),2),0) AS `PMPERMDOCK` 
, COALESCE(TRUNCATE(SUM(
    CASE 
    WHEN (shift='PM' AND DriverDock = 'Dock' AND `Salary Code Description` LIKE '%Cas%') 
     THEN 
     CASE 
     WHEN paycode IN ('03 Overtime 2.0') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 2.0) 
     WHEN paycode IN ('02 Overtime 1.5') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 1.5) 
     WHEN paycode IN ('01 Ordinary') 
      THEN (employeehours * p.`Base Rate`) 
     END 
    END 
    ),2),0) AS `PMCASUDOCK` 
, COALESCE(TRUNCATE(SUM(
    CASE 
    WHEN (shift='PM' AND DriverDock = 'Dock' AND `Salary Code Description` LIKE '%AGENT%') 
     THEN 
     CASE 
     WHEN paycode IN ('03 Overtime 2.0') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 2.0) 
     WHEN paycode IN ('02 Overtime 1.5') 
      THEN (employeehours * IF(p.`Other Rate`=0,p.`Base Rate`,p.`Other Rate`) * 1.5) 
     WHEN paycode IN ('01 Ordinary') 
      THEN (employeehours * p.`Base Rate`) 
     END 
    END 
    ),2),0) AS `PMAGENTDOCK` 
FROM employeedata d 
JOIN employeehours h 
ON d.`ID Number` = h.employeeid 
JOIN historyemployeepay p 
ON (h.employeeid = p.EmployeeID) 
AND (h.workdate >= p.FromDate) 
AND (h.workdate <= p.ToDate OR p.ToDate IS NULL) 
CROSS 
JOIN otherrates r 
WHERE DAYNAME(h.workdate) <> 'Saturday' 
GROUP BY h.workdate 

我有以下的HTML表格,我怎麼可以在查詢結果和DISP環正確佈局?:

<?php 
    $querydailyoperations=mysql_query(" 
            QUERY ABOVE 
    "); 
while($querydailyoperationsshow=mysql_fetch_array($querydailyoperations)){ echo "??????????";}; 
?> 

和:

<tr><td class="greencell">AM</td><td class="greencell">PERMANENT</td><td class="greencell">DRIVER</td>5x td here, input from above query... 
</tr> 
<tr><td class="greencell">AM</td><td class="greencell">PERMANENT</td><td class="dbluecell">DH</td> etc... 
</tr> 
<tr><td class="greencell">AM</td><td class="orangecell">CASUAL</td><td class="greencell">DRIVER</td> etc... 
</tr> 
<tr><td class="greencell">AM</td><td class="orangecell">CASUAL</td><td class="dbluecell">DH</td> etc... 
</tr> 
<tr><td class="greencell">AM</td><td nowrap class="redcell">AGENT LABOUR</td><td class="greencell">DRIVER</td> etc... 
</tr> 
<tr><td class="greencell">AM</td><td nowrap class="redcell">AGENT LABOUR</td><td class="dbluecell">DH</td> etc... 
</tr> 
<tr><td class="bluecell">PM</td><td class="greencell">PERMANENT</td><td class="greencell">DRIVER</td> etc... 
</tr> 
<tr><td class="bluecell">PM</td><td class="greencell">PERMANENT</td><td class="dbluecell">DH</td> etc... 
</tr> 
<tr><td class="bluecell">PM</td><td class="orangecell">CASUAL</td><td class="dbluecell">DH</td> etc... 
</tr> 
<tr><td class="bluecell">PM</td><td nowrap class="redcell">AGENT LABOUR</td><td class="dbluecell">DH</td> etc... 
</tr> 
</tbody> 
</table> 
+0

如果我正確理解這個問題,這與你的MySQL查詢無關。按照您想要的方式格式化數據的正確方法是使用PHP循環並構建HTML以符合所需的規範,並使用CSS實現外觀和感覺。 –

+0

這就是我想要做的,但我似乎無法得到我的頭,我會在編碼中添加..謝謝brian – atomapps

+0

沒問題,編輯你的問題,並張貼你有什麼代碼我會幫你解決的。 –

回答

1

很可能得到使用SQL查詢的結果,但這不是微不足道的。


但是在你走這條路線之前,我建議你考慮一種不同的方法。

由於查詢返回一個相對較小的行集,你可以代替檢索整個結果集到PHP爲一個二維數組。

考慮一個相當簡單的情況下,作爲一個例證:

SELECT foo, fee, fi, fo, fum 
    FROM mytable 
ORDER BY foo 

foo fee fi fo fum 
--- --- --- --- --- 
ABC 2 3 5 7 
DEF 11 13 17 19 

我們可以做一個使用fetchall,並得到一個二維數組,然後通過數組循環和檢索值列明智的,而不是排-明智的。一個選擇是我們收到的數組轉換成一個新的陣列看起來像這樣:

bar ABC DEF 
--- --- --- 
fee 2 11 
fi  3 13 
fo  5 17 
fum 7 19 

這是不是真的有必要做的改造,你可以漫步在原始數組。但是當你實際生成輸出到頁面中時,將轉換分離爲單獨的步驟可能會使代碼更容易一些。 (這似乎是一個足夠常見的問題,有人可能已經寫,你想要做,我不認爲有一個PHP內置的,做它的陣列轉換功能

標題:。

array { [0]=>'bar' [1]=>'ABC' [2]=>'DEF' } 

行:

array { 
    [0]=>array { [0]=>'fee' [1]=>'2' [2]=>'11' } 
    [1]=>array { [0]=>'fi' [1]=>'3' [2]=>'13' } 
    [2]=>array { [0]=>'fo' [1]=>'5' [2]=>'17' } 
    [3]=>array { [0]=>'fum' [1]=>'7' [2]=>'19' } 
} 

對於一小行的像你這樣,我會選擇這樣做的PHP,而不是在SQL


但你問了如何在SQL中完成它。正如我剛纔所說,這不是微不足道的。

SQL要求SELECT語句定義要返回的每一列;當語句執行時,列的數量和類型不能是動態的。

如果我們構建定義列的另一個查詢(除原始查詢之外),並返回我們期望返回的值與佔位符的值,那麼我們已經到了一半。剩下的就是對原始查詢返回的行進行外連接,並有條件地返回適當行上的列值。

如果您有一組預定義的行和列需要返回,特別是在原始行源非常稀疏的情況下,我們需要生成「缺失」行。 (例如,獲取產品計數有序的,而且有很多缺失的行,有沒有產生缺失行的好辦法

例如:

SELECT r.bar 
    , '' AS `ABC` 
    , '' AS `DEF` 
    FROM (SELECT 'fee' AS bar 
      UNION ALL SELECT 'fi' 
      UNION ALL SELECT 'fo' 
      UNION ALL SELECT 'fum' 
     ) r 
GROUP BY r.bar 

,將返回:

bar ABC DEF 
--- --- --- 
fee 
fi 
fo 
fum 

因此,我們得到了所有定義的列,以及我們想返回的所有行。第一列已填充。該查詢實際上並不需要GROUP BY,但我們需要它一旦匹配來自「真實」源結果集中的行,就會發生這種情況

現在「技巧」是匹配來自我們源的行,並根據適當的條件從列中返回值。

什麼,我們要產生,本質上是一個結果集,看起來像這樣:

bar foo ABC DEF 
--- --- --- --- 
fee ABC 2 
fee DEF  11 
fi ABC 3 
fi DEF  13 
fo ABC 5 
fo DEF  15 
fum ABC 7 
fum DEF  17 

然後我們要「崩潰」的行,通過從結果集foo的列和做GROUP BY bar。我們將使用聚合函數(或者MAX或SUM)的,他們用NULL值做處理利用,產生這樣的這樣的結果:

bar foo ABC DEF 
--- --- --- --- 
fee   2 11 
fi   3 13 
fo   5 15 
fum   7 17 

使用這種相當笨重SQL:

SELECT r.bar 
    , MAX(CASE WHEN t.foo = 'ABC' THEN CASE r.bar 
     WHEN 'fee' THEN t.fee 
     WHEN 'fi' THEN t.fi 
     WHEN 'fo' THEN t.fo 
     WHEN 'fum' THEN t.fum 
     END END) AS 'ABC' 
    , MAX(CASE WHEN t.foo = 'DEF' THEN CASE r.bar 
     WHEN 'fee' THEN t.fee 
     WHEN 'fi' THEN t.fi 
     WHEN 'fo' THEN t.fo 
     WHEN 'fum' THEN t.fum 
     END END) AS 'DEF' 
    FROM (SELECT 'foo' AS col 
      UNION ALL SELECT 'fee' 
      UNION ALL SELECT 'fi' 
      UNION ALL SELECT 'fo' 
      UNION ALL SELECT 'fum' 
     ) r 
CROSS 
    JOIN mysource t 
GROUP BY r.bar 

注意mysource在上面的查詢可以使用內嵌視圖所取代,纏繞返回我們想要的行合適的查詢括號。

別名爲r的內聯視圖是返回我們想返回的行的源碼。

SELECT列表中的表達式正在執行條件測試,爲每行中的每列選取正確的值。

鑑於CASE語句的常規模式,可以使用一些SQL來幫助生成查詢,但這必須作爲單獨的步驟完成。該SQL的輸出可用於幫助形成我們需要的實際查詢。

在你的情況下,假設workdate是你想要用於列標題,這很可能必須動態生成。 (您可以從原始源查詢中刪除'第幾天'的第二列,然後將其移至外部查詢。

如果我在運行查詢之前不知道標題的workdate值,那麼我會選擇創建TEMPORARY TABLE並用原始查詢的結果填充它,然後查詢臨時表以得到workdate標題,並且「第一列」生成行。然後我會對臨時表運行實際的查詢。


要再說一遍,我想你會更好,在PHP原始查詢執行結果的變換/支點,而不是試圖做到這一點的SQL。