簡體   English   中英

使用PHP從三個MySQL表構建CSV表的有效方法

[英]Efficient way to build CSV table from three MySQL tables with PHP

我想使用PHP從數據庫中的數據構建CSV表。 我正在編程的應用程序可以對孩子進行評分。 我的第一張桌子只定義了孩子:

┏━━━━┳━━━━━━┓
┃ ID ┃ name ┃
┡━━━━╇━━━━━━┩
│  1 │ John │
│  2 │ Lucy │
│  3 │ Zara │
└────┴──────┘

第二個定義事件,孩子可以在其中獲得積分

┏━━━━┳━━━━━━━━━━━━┓
┃ ID ┃    date    ┃
┡━━━━╇━━━━━━━━━━━━┩
│  1 │ 2016-12-31 │
│  2 │ 2017-01-07 │
│  3 │ 2017-01-14 │
│  4 │ 2017-01-21 │
└────┴────────────┘

第三個告訴我們在eventID為eventID的事件中獲得childID為childID的點數

┏━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┓
┃ ID ┃ eventID ┃ childID ┃ points ┃
┡━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━┩
│  1 │       1 │       1 │     21 │
│  2 │       1 │       2 │     43 │
│  3 │       1 │       3 │      4 │
│  4 │       2 │       1 │      8 │
│  5 │       2 │       2 │     15 │
│  6 │       2 │       3 │     13 │
│  7 │       3 │       1 │     34 │
│  8 │       3 │       2 │     40 │
│  9 │       3 │       3 │     20 │
│ 10 │       4 │       1 │      3 │
│ 11 │       4 │       2 │      7 │
│ 12 │       4 │       3 │      9 │
└────┴─────────┴─────────┴────────┘

假設我們有C個子事件和E個事件,因此表點具有C * E行。 現在,我想找到構建表的最有效方法,如下所示:

     event;John;Lucy;Zara;⋯
2016-12-31;  21;  43;   4;
2017-01-07;   8;  15;  13;
2017-01-14;  34;  40;  20;
2017-01-21;   3;   7;   9;
     ⋮                   ⋱

它也可以被row <-> col交換,但是我的活動比孩子更多。

但是我對數據庫進行C乘E次查詢並不滿意。 我試過用PHP生成冗長而丑陋的查詢,但它基本上也使C乘以E子查詢。 我也有想法如何僅使用E查詢來構建它,但是僅使用一個查詢是不可能的嗎?

考慮條件聚合,在MySQL中,您必須對每個子名稱進行繁瑣的操作。 如果太多(數百個)不可行,請考慮使用PHP動態構建SQL字符串。

SELECT e.date AS `event`, 
       SUM(CASE WHEN c.name = 'John' THEN j.points ELSE 0 END) As `John`,
       SUM(CASE WHEN c.name = 'Lucy' THEN j.points ELSE 0 END) As `Lucy`,
       SUM(CASE WHEN c.name = 'Zara' THEN j.points ELSE 0 END) As `Zara`   
FROM EventChildJoin j
INNER JOIN ChildTable c
   ON j.childID = c.ID
INNER JOIN EventTable e
   ON j.eventID = e.ID
GROUP BY e.date

如前所述,由於MySQL沒有交叉表/數據透視圖方法,因此必須在應用程序層構建SQL,然后傳遞到數據庫層進行處理。 這是PHP的示例:

try {
    $dbh = new PDO("mysql:host=$hostname;dbname=$database",$username,$password);    

    # FIRST FETCH
    $strSQL = "SELECT DISTINCT name FROM ChildTable";
    $STH = $dbh->query($strSQL);
    $STH->setFetchMode(PDO::FETCH_ASSOC);

    $strSQL = "SELECT e.date AS `event`, ";    
    while($row = $STH->fetch()) {  
        $strSQL = $strSQL . " SUM(CASE WHEN c.name = '". row['name'] ."' " .
                            "          THEN j.points ELSE 0 END) As `". row['name'] ."`,";
    }

    $strSQL = " FROM EventChildJoin j".
              " INNER JOIN ChildTable c ".
              "      ON j.childID = c.ID ".
              " INNER JOIN EventTable e ".
              "      ON j.eventID = e.ID ".
              " GROUP BY e.date;";
    $strSQL = str_replace(", FROM", " FROM", strSQL)    # REMOVE COMMA AFTER LAST COLUMN

   # NEXT FETCH
   $STH = null;
   $STH = $dbh->query($strSQL);
   $STH->setFetchMode(PDO::FETCH_ASSOC);
   ...    
}

catch(PDOException $e) {  
    echo $e->getMessage();
    exit;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM