将数据水平获取到html表中

问题描述 投票:2回答:2

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

// 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表的表:

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)          |
php html mysql
2个回答
2
投票

从我看到的是,当你从不同的表中获取数据时,你在while循环中进行while循环,我认为在这种情况下很难跟踪和合并它们。所以我建议,首先从你的项目表中获取所有数据并做好准备。

EG

/** 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

虽然上面的代码仍然可以改进,但这应该会让你有一个快速的开始。

UPDATE

关于获取相同的两列,您可以添加$titles = array_unique($titles);以摆脱重复的列。你把它放在while ($data = $res->fetch_assoc()) {块之后。

/** 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

0
投票

试试这个:

while ($data2 = mysqli_fetch_assoc($query2)) {
    $projectN = $data['projectNo'];
    $code = $data['code'];      
    $title = $data['title'];
    $projectNo = $data2['projectNo'];
    $process = $data2['process'];
    $count = $data2['count'];

    // Here instead of overwriting, save process names in an array
    if (!isset($projectNoToTitle[$projectNo])) {
        $projectNoToTitle[$projectNo] = [];
    }
    $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;
    }
}

然后在格式化代码中,您需要更改以下几项:

$header =
    '<th>Code</th>
    <th>Title</th>' .
    array_reduce(array_values($projectNoToTitle), function ($p, $n) {
        // now $n is an array so implode it
        $header = '';
        foreach ($n as $p) {
            $header .= '<th>Process ' . htmlspecialchars($n)) . '</th>'
        }
        return $p . $header;
    });

// 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])
            // again, this is a brutal hack, you may rewrite part of
            // the code to do the same thing if you like.
            ? implode('</td><td>', $titleData['projects'][$projectNo])
            : 'N/A';
        $row .= '<td>' . htmlspecialchars($r) . '</td>';
    }
    $body .= "<tr>$row</tr>";
}
echo "<thead>$header</thead><tbody>$body</tbody>";

请注意,如果每个项目都没有相同的进程,这将不起作用,但也许你明白了。你的问题无论如何都不清楚,因为你没有提供一个样本表中包含更多的进程,所以我不知道你想要做什么。

无论如何,问题是你每次都要覆盖进程名称。希望能帮助到你!

© www.soinside.com 2019 - 2024. All rights reserved.