繁体   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