簡體   English   中英

需要將來自多個MySql表的信息組合到html表中的diaply

[英]Need to combine info from multiple MySql tables to diaply in html table

我很難找到最好的辦法。 我在mysql中有三個表,這與健身房應用程序構建有關,一個用於肌肉鍛煉,一個用於有氧運動,另一個用於容納用戶每天鍛煉的結果。 每天鍛煉的基礎是0到1次有氧運動和0 - 但是私人教練決定進行多次肌肉鍛煉。 在鍛煉結束時,用戶將每個鍛煉的結果放入表格並提交。 結果只是一個文本字段。 我有一個數據庫,為每個包含的結果創建一行

username,exercise type (muscle,cardio),exercise name, exercise result, date

所以一個例子就是

John,muscle,bench press, 225lb max out, 2012-08-21
John,cardio,rowing,12 miles, 2012-08-21

然后,我想要獲取此信息並按照所選日期在標准表中顯示。 因此,每個日期有多個用戶,每個用戶可以有多個答案。 標題是

username,cardio, muscle 1, muscle 2 ect.. (顯示當天的數量)然后結果下降並填寫表格。

除了進行幾十個選擇調用之外,我試圖找到一種方法來做到這一點。 我打算嘗試創建一些排序或數組並使用它。 有任何想法嗎?

我會選擇陣列。 問題在於調度肌肉/心臟結果。

要格式化HTML並獲得標題,假設我們首先是有氧運動,然后是肌肉運動。

因此,您選擇該日期的所有行,按用戶名和有氧運動/肌肉進行排序。

然后:

$users = array();
$maxes = array('cardio' => 0, 'muscle' => 0);

foreach($row = ...)
{
    list($user, $com, $name, $result) = $row;
    if (!isset($users[$user]))
        $userData = array('cardio' => array(), 'muscle' => array());
    else
        $userData = $users[$user];
    $userData[$com][] = array($name, $result);
    if (count($userData[$com]) > $maxes[$com])
        $maxes[$com] = count($userData[$com]);
    $users[$user] = $userData;
}

現在你有類似的東西:

'John': {
     'cardio': [
        [ 'rowing', '12 miles' ],
        [ 'running', '2 miles' ],
     ],
     'muscle': [ ]
},
'Jack': {
     'cardio': [ ],
     'muscle': [ 'bench', '300lbs' ],
}

要在HTML中格式化,我們已經保存了任何用戶的最大心肺數量和最大肌肉數量。 因此,1 + MaxC + MaxM列的表將包含所有用戶,訂購:

Name  Cardio 1    Cardio 2   Muscle 1

John  Rowing      Running    -
      12 miles    2 miles
Jack  -           -          Bench
                             300lbs

並建立它:

// First the header
print "<tr>";
print "<th>Name</th>";
for ($i = 0; $i < $maxes['cardio']; $i++)
    print "<th>Cardio " . ($i+1) . "</th>";
for ($i = 0; $i < $maxes['muscle']; $i++)
    print "<th>Muscle ($i+1)</th>";
print "</tr>";

foreach($users as $user => $info)
{
    print "<tr><td>$user</td>";
    foreach(array('cardio','muscle') as $key)
    {
        $data = $info[$key];
        for ($i = 0; $i < $maxes[$key]; $i++)
        {
            print "<td>";
            if (isset($data[$i]))
            {
                list($name, $result) = $data[$i];
                print "$name<br />$result";
            }
            else print '-';
            print "</td>";  
        } 
    }
    print "</tr>";
 }

我建議4個表用於3NF設置:

user (username PK)
exercise_type (type PK)
exercise_name (name PK)
exercise_entry (id PK, username FK, date, exercise_type FK, exercise_name FK, result)

你會產生鍛煉條目exercise_entry和離開的結果NULL 這樣,用戶知道存在預期的值。

在PHP端,您只需根據過濾器參數從exercise_entry表中獲取數據。

編輯1

如果練習類型和名稱之間存在1:1的關系,則可以使用3表格方法。

user (username PK)
exercise_name (name PK, type)
exercise_entry (id PK, username FK, date, exercise_name FK, result)

首先,可能沒有必要為三類運動中的每一類都有單獨的表格:也許只需一個exercises表就足夠了,用一列來表明每條記錄是肌肉運動還是心血管運動?

在你的問題:你正在試圖做的是轉動你的數據,這是MySQL的開發人員故意本身不包括在內(因為他們覺得這是更適合演示,而不是數據庫,應用層功能); 其他RDBMS可能對此類操作有更多本機支持。 但是,通過數據進行分組並使用MySQL的GROUP_CONCAT()函數聚合結果,仍然可以實現您所尋求的目標:

SELECT   username,
         GROUP_CONCAT(IF(exercise='bench press',result,NULL)) AS `bench press`,
         GROUP_CONCAT(IF(exercise='rowing'     ,result,NULL)) AS `rowing`,
         -- etc.
FROM     results
WHERE    date = '2012-08-21'
GROUP BY username

如果練習列表是動態的,您可以生成包含此SQL語句的字符串,然后從該字符串中准備並執行語句:

SELECT CONCAT('
   SELECT   username,
', GROUP_CONCAT(
     'GROUP_CONCAT(IF(exercise=',QUOTE(name),',result,NULL))'
   ,    ' AS `',REPLACE(name,'`','``'),'`'
   )
,' FROM     results
   WHERE    date = ?
   GROUP BY username
') FROM exercises INTO @sql;
PREPARE stmt FROM @sql;
EXECUTE stmt USING '2012-08-21';
DEALLOCATE PREPARE stmt;

暫無
暫無

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

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