php - 水平获取数据到html表格中

标签 php html mysql

我想从数据库中获取数据并相应地水平和垂直打印。我有一个项目表,每个项目内可以有多个进程。对于每个流程,都有许多指定的人员。 所以我所做的就是首先获取有关项目的信息:

// 1.Get data
// data for final table
$result = [];
// map project no to its title
$projectNoToTitle = [];
$sql = '
    SELECT projectNo, code, title
    FROM `project`
    ORDER BY projectNo
';
$query = mysqli_query($conn, $sql);

然后,对于每个项目,我尝试获取流程并计算每个 user_type 中的人数:

// for each process
while ($data = mysqli_fetch_assoc($query)) {

    $sql2 = '
            SELECT projectNo, process, GROUP_CONCAT(col separator "+") as `count`
            FROM 
            (
                SELECT projectNo, process, concat(count(*),"(",user_type,")") as `col`
                FROM
                (
                    (
                         SELECT * FROM proc_leader t1 
                            LEFT JOIN
                            (
                                 SELECT username, user_type FROM user GROUP BY username
                            ) t2 ON t1.proc_leader = t2.username GROUP BY t1.proc_leader                    
                    )
                    UNION
                    (
                         SELECT * FROM proc_checker t1 
                            LEFT JOIN
                            (
                                SELECT username, user_type FROM user GROUP BY username
                            ) t2 ON t1.proc_checker = t2.username GROUP BY t1.proc_checker                          
                    )
                    UNION
                    (
                         SELECT * FROM proc_staff t1 
                            LEFT JOIN
                            (
                                SELECT username, user_type FROM user GROUP BY username
                            ) t2 ON t1.proc_staff = t2.username GROUP BY t1.proc_staff                                      
                    )  
                ) AS a GROUP BY projectNo, process, user_type
            ) t GROUP BY projectNo, process 
    ';
    $query2 = mysqli_query($conn, $sql2);
    // for each project => process pair of user
    while ($data2 = mysqli_fetch_assoc($query2)) {
        $projectN = $data['projectNo'];
        $code = $data['code'];      
        $title = $data['title'];
        $projectNo = $data2['projectNo'];
        $process = $data2['process'];
        $count = $data2['count'];

        $projectNoToTitle[$projectNo] = $process;

        if (!isset($result[$title])) {
            $result[$title] = [ 'code' => $code, 'projects' => []];
        }
        if (!isset($result[$title]['projects'][$projectNo])) {
            $result[$title]['projects'][$projectNo] = [];
        }
        if ($count) {
            $result[$title]['projects'][$projectNo][] = $count;
        }
    }
}

然后我尝试打印我的表格:

<table>
<?php
// 2. Output table
// create table header
// it's columns should contain all processes
if ($result) 
{
    $header =
        '<th>Code</th>
        <th>Title</th>' .
        array_reduce(array_values($projectNoToTitle), function ($p, $n) {
            return $p . '<th>Process ' . htmlspecialchars($n) . '</th>';
        });

    // output body
    $body = '';
    foreach ($result as $title => $titleData) 
    {
        $row = '<td>' . htmlspecialchars($titleData['code']) . '</td>' . '<td>' . htmlspecialchars($title) . '</td>';
        foreach ($projectNoToTitle as $projectNo => $projectTitle) 
        {
            $r = isset($titleData['projects'][$projectNo])
                ? implode(', ', $titleData['projects'][$projectNo])
                : 'N/A';
            $row .= '<td>' . htmlspecialchars($r) . '</td>';
        }
        $body .= "<tr>$row</tr>";
    }
    echo "<thead>$header</thead><tbody>$body</tbody>";
}// \2. Output table
?>
</table>

我的预期输出是:

| projectNo | code |   title   | Process ANM BGR | Process BLD COL |Process BGA CDP |
+-----------+------+-----------+-----------------+-----------------+----------------+
| 170001    |  pr1 |  Project1 |   1(FT)+1(CT)   |       1(AP)     |                |
| 170002    |  pr2 |  Project2 |                 |                 | 1(CT)          |

但我得到的是:

| projectNo | code |   title   |        Process BGD COL    |        Process BGA CDP    |
+-----------+------+-----------+---------------------------+---------------------------+
| 170001    |  pr1 |  Project1 |    1(CT)+1(FT), 1(AP)     |         1(CT)             |
| 170002    |  pr2 |  Project2 |    1(CT)+1(FT), 1(AP)     |         1(CT)             |

如何将每个进程排列为列?谢谢您

编辑

项目表的表:

project table:
| projectNo | code |   title  |
+-----------+------+----------+
| 170001    | pr1  | Project1 |
| 170002    | pr2  | Project2 |

process table:
| projectNo | process |
+-----------+---------+
| 170001    | ANM BGR |
| 170001    | BGD COL |
| 170002    | BGA CDP |

username table:
| uid | username   | user_type|
+-----+------------+----------+
| 1   | AARONJAMES | CT       |
| 2   | ADELINE    | AP       |
| 3   | AARONKOH   | CT       |
| 4   | AHMAD      | FT       |

proc_leader table:
| projectNo | process | proc_leader|
+-----------+---------+------------+
| 170001    | ANM BGR | AARONJAMES |
| 170001    | BGD COL | ADELINE    |
| 170002    | BGA CDP | AARONKOH   |

proc_checker table:
| projectNo | process | proc_checker |
+-----------+---------+--------------+
| 170001    | ANM BGR |  AARONJAMES  |
| 170001    | BGD COL |  AARONJAMES  |
| 170002    | BGA CDP |  AARONKOH    |

proc_staff table:
| projectNo | process | proc_staff |
+-----------+---------+------------+
| 170001    | ANM BGR |    AHMAD   |

编辑2

更新答案后我得到的是:

enter image description here正如您所看到的,过程是重复的。但我需要它在 1 列以下。 像这样:

| projectNo | code |   title   | Process ANM BGR | Process BLD COL |Process BGA CDP |
+-----------+------+-----------+-----------------+-----------------+----------------+
| 170001    |  pr1 |  Project1 |   1(FT)+1(CT)   |       1(AP)     |                |
| 170002    |  pr2 |  Project2 |     2(CT)       |                 | 1(CT)          |

最佳答案

据我所知,当从不同的表中获取数据时,您正在 while 循环内执行 while 循环,我认为在这种情况下很难同时跟踪和合并它们。 所以我建议,首先从项目表中获取所有数据,然后进行处理。

例如

/** start for getting projects **/
$query = 'SELECT projectNo, code, title
          FROM `project`
          ORDER BY projectNo';

$res = $con->query($query);
$projects = [];
while ($data = $res->fetch_assoc()) {
    $projects[] = $data;
}
/** end for getting projects **/

然后执行另一个查询以从不同的表获取数据并执行 while 循环。 因此,一旦获得所需的所有数据,您就可以在 html 上制作表格时轻松合并它们。

检查我的工作代码:

/** start for getting projects **/
$query = 'SELECT projectNo, code, title
          FROM `project`
          ORDER BY projectNo';

$res = $con->query($query);
$projects = [];
while ($data = $res->fetch_assoc()) {
    $projects[] = $data;
}
/** end for getting projects **/


$titles = array();
$query = 'SELECT projectNo, process, GROUP_CONCAT(col separator "+") as `count`
          FROM 
          (
            SELECT projectNo, process, concat(count(*),"(",user_type,")") as `col`
            FROM
            (
                (
                     SELECT * FROM proc_leader t1 
                        LEFT JOIN
                        (
                             SELECT username, user_type FROM user GROUP BY username
                        ) t2 ON t1.proc_leader = t2.username GROUP BY t1.proc_leader                    
                )
                UNION
                (
                     SELECT * FROM proc_checker t1 
                        LEFT JOIN
                        (
                            SELECT username, user_type FROM user GROUP BY username
                        ) t2 ON t1.proc_checker = t2.username GROUP BY t1.proc_checker                          
                )
                UNION
                (
                     SELECT * FROM proc_staff t1 
                        LEFT JOIN
                        (
                            SELECT username, user_type FROM user GROUP BY username
                        ) t2 ON t1.proc_staff = t2.username GROUP BY t1.proc_staff                                      
                )  
            ) AS a GROUP BY projectNo, process, user_type 
          ) AS t GROUP BY projectNo, process';

$res = $con->query($query);
/** process the data first and store to variables and arrays **/
while ($data = $res->fetch_assoc()) {
    $projectNo = $data['projectNo'];
    $processName = $data['process'];
    $titles[] = $processName;
    $count = $data['count'];

    if (!isset($allProcess[$projectNo])) 
        $allProcess[$projectNo] = [];

    if ($count) 
        $allProcess[$projectNo][$processName] = $count;
}
?>

<style>
  table, th, td {
    border: 1px solid #000;
  }
</style>
<table>
<?php
/** now do the printing of data **/
if ($allProcess)  {
    $header =
        '<th>ProjectNo</th>
         <th>Code</th>
         <th>Title</th>' .
        array_reduce(array_values($titles), function ($p, $n) {
            return $p . '<th>Process ' . htmlspecialchars($n) . '</th>';
        });

    $body = '';
    /** loop through projects first instead **/
    foreach ($projects as $p) {
        $body .= '<tr>';
        $body .= '<td>' . htmlspecialchars($p['projectNo']) . '</td>' . '<td>' . htmlspecialchars($p['code']) . '</td>' . '<td>' . htmlspecialchars($p['title']) . '</td>';

        /** loop through titles or all process **/
        foreach ($titles as $t) {
            $row = $allProcess[$p['projectNo']]; // e.g. Array ( [process] => Array ( [170001]...
            $r = isset($row) && isset($row[$t]) ? $row[$t] : 'N/A';
            $body .= '<td>' . htmlspecialchars($r) . '</td>';
        }
        $body .= '</tr>';
    }


    echo "<thead>$header</thead><tbody>$body</tbody>";
}
?>
</table>

截图: enter image description here

尽管上面的代码仍有一些可以改进的地方,但这应该可以让您快速开始。

更新

关于获取相同的两列,您可以添加 $titles = array_unique($titles); 来删除重复的列。您将其放在 while ($data = $res->fetch_assoc()) { block 之后。

/** process the data first and store to variables and arrays **/
$rows = [];
while ($data = $res->fetch_assoc()) {
    $rows[] = $data;
    $projectNo = $data['projectNo'];
    $processName = $data['process'];
    $titles[] = $processName;
    $count = $data['count'];

    if (!isset($allProcess[$projectNo])) 
        $allProcess[$projectNo] = [];

    if ($count) 
        $allProcess[$projectNo][$processName] = $count;
}

$titles = array_unique($titles); // the fix

关于php - 水平获取数据到html表格中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41800711/

相关文章:

php - Zend 数组分页

PHP/MYSQL 复制插入语句的最后一行

Javascript 像素操作 : These aren't my colors

mysql - App.objects.get(foo=bar) 没有 'order_by' 属性

javascript - PHP - 读取文本文件时出现问题

php - 如何在不使用 Web 应用程序的情况下在常规 HTML 页面中显示 JavaScript、PHP 和其他 Web 开发语言的源代码?

html - 为什么我的 CSS 不合作?

html - 中心图标 + CSS 上的文本悬停图像

mysql - SQL更新触发器加减

mysql - 排除嵌套 SQL 查询的结果