You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PHP、MySQL和HTML隐藏查询数据中的重复内容

解决查询结果重复字段隐藏的问题

首先得指出你当前代码里的一个小问题:你用了GROUP BY tally_head.head,这会导致每个tally_head.head只返回一条记录,但实际上你应该是想展示每个凭证(entry)对应的所有ledger条目,只是希望隐藏前面重复的凭证信息,对吧?所以第一步要调整SQL,去掉GROUP BY,保留所有关联的数据,确保我们能拿到每个凭证对应的所有ledger记录:

SELECT 
    entry.id as cid,
    entry.payorder,
    entry.bank,
    entry.PFMS_SCHEME,
    entry.name,
    entry.vendor,
    tally_head.head,
    ledgers.amount,
    entry.po,
    entry.Description,
    bank_details.Name as party_name, -- 重命名避免和entry.name冲突
    entry.sum as total_sum
FROM entry
JOIN bank_details ON entry.name = bank_details.id
JOIN ledgers ON ledgers.id = entry.id
JOIN tally_head ON ledgers.ledger = tally_head.id
ORDER BY entry.id, tally_head.head; -- 按凭证ID排序,确保同凭证的记录排在一起

接下来给你两种实现隐藏重复内容的方案,根据你的需求选择:

方案一:简单隐藏重复内容(留空)

这个方案很直观,我们在PHP里记录上一行的凭证ID(cid),每次循环时对比当前行和上一行的cid,如果相同,就把前面重复的字段内容留空,否则正常显示并更新上一行的cid:

<table class="table">
    <thead>
        <tr>
            <th>Voucher No </th>
            <th>Payorder </th>
            <th>Bank </th>
            <th>PFMS_SCHEME </th>
            <th>Party Name </th>
            <th> For</th>
            <th> Po/agmt/inv N.o </th>
            <th>Ledger</th>
            <th>Ledger Amount</th>
            <th>Description/ Narration</th>
            <th>sum</th>
        </tr>
    </thead>
    <tbody>
        <?php
        $sql = mysqli_query($con, "SELECT 
            entry.id as cid,
            entry.payorder,
            entry.bank,
            entry.PFMS_SCHEME,
            entry.name,
            entry.vendor,
            tally_head.head,
            ledgers.amount,
            entry.po,
            entry.Description,
            bank_details.Name as party_name,
            entry.sum as total_sum
        FROM entry
        JOIN bank_details ON entry.name = bank_details.id
        JOIN ledgers ON ledgers.id = entry.id
        JOIN tally_head ON ledgers.ledger = tally_head.id
        ORDER BY entry.id, tally_head.head");
        
        $prev_cid = null; // 记录上一行的凭证ID
        while($row = mysqli_fetch_array($sql)) {
            $is_same_entry = ($row['cid'] == $prev_cid);
        ?>
        <tr>
            <td><?php echo $is_same_entry ? '' : htmlentities($row['cid']);?></td>
            <td><?php echo $is_same_entry ? '' : htmlentities($row['payorder']);?></td>
            <td><?php echo $is_same_entry ? '' : htmlentities($row['bank']);?></td>
            <td><?php echo $is_same_entry ? '' : htmlentities($row['PFMS_SCHEME']);?></td>
            <td><?php echo $is_same_entry ? '' : htmlentities($row['party_name']);?></td>
            <td><?php echo $is_same_entry ? '' : htmlentities($row['vendor']);?></td>
            <td><?php echo $is_same_entry ? '' : htmlentities($row['po']);?></td>
            <td><?php echo htmlentities($row['head']);?></td>
            <td><?php echo htmlentities($row['amount']);?></td>
            <td><?php echo $is_same_entry ? '' : htmlentities($row['Description']);?></td>
            <td><?php echo $is_same_entry ? '' : htmlentities($row['total_sum']);?></td>
        </tr>
        <?php
            $prev_cid = $row['cid']; // 更新上一行的凭证ID
        }
        ?>
    </tbody>
</table>

方案二:使用HTML rowspan合并单元格(更美观专业)

如果想要更整洁的表格效果,推荐用rowspan合并相同凭证的单元格,这样重复的字段会跨多行显示,视觉体验更好。实现思路是先把数据按凭证ID分组,统计每个凭证对应的记录行数,然后在循环时给第一行的重复字段设置rowspan属性,后续行不再输出这些单元格:

<table class="table">
    <thead>
        <tr>
            <th>Voucher No </th>
            <th>Payorder </th>
            <th>Bank </th>
            <th>PFMS_SCHEME </th>
            <th>Party Name </th>
            <th> For</th>
            <th> Po/agmt/inv N.o </th>
            <th>Ledger</th>
            <th>Ledger Amount</th>
            <th>Description/ Narration</th>
            <th>sum</th>
        </tr>
    </thead>
    <tbody>
        <?php
        // 先获取所有数据并按凭证ID分组
        $sql = mysqli_query($con, "SELECT 
            entry.id as cid,
            entry.payorder,
            entry.bank,
            entry.PFMS_SCHEME,
            entry.name,
            entry.vendor,
            tally_head.head,
            ledgers.amount,
            entry.po,
            entry.Description,
            bank_details.Name as party_name,
            entry.sum as total_sum
        FROM entry
        JOIN bank_details ON entry.name = bank_details.id
        JOIN ledgers ON ledgers.id = entry.id
        JOIN tally_head ON ledgers.ledger = tally_head.id
        ORDER BY entry.id, tally_head.head");
        
        $entries = [];
        while($row = mysqli_fetch_array($sql)) {
            $cid = $row['cid'];
            if(!isset($entries[$cid])) {
                $entries[$cid] = [];
            }
            $entries[$cid][] = $row;
        }
        
        // 遍历分组后的凭证数据
        foreach($entries as $cid => $rows) {
            $row_count = count($rows); // 当前凭证对应的记录行数
            $first_row = true;
            foreach($rows as $row) {
        ?>
        <tr>
            <?php if($first_row): ?>
            <!-- 第一行设置rowspan,跨所有同凭证的行 -->
            <td rowspan="<?php echo $row_count;?>"><?php echo htmlentities($row['cid']);?></td>
            <td rowspan="<?php echo $row_count;?>"><?php echo htmlentities($row['payorder']);?></td>
            <td rowspan="<?php echo $row_count;?>"><?php echo htmlentities($row['bank']);?></td>
            <td rowspan="<?php echo $row_count;?>"><?php echo htmlentities($row['PFMS_SCHEME']);?></td>
            <td rowspan="<?php echo $row_count;?>"><?php echo htmlentities($row['party_name']);?></td>
            <td rowspan="<?php echo $row_count;?>"><?php echo htmlentities($row['vendor']);?></td>
            <td rowspan="<?php echo $row_count;?>"><?php echo htmlentities($row['po']);?></td>
            <td rowspan="<?php echo $row_count;?>"><?php echo htmlentities($row['Description']);?></td>
            <td rowspan="<?php echo $row_count;?>"><?php echo htmlentities($row['total_sum']);?></td>
            <?php endif; ?>
            <!-- 每次都显示的ledger相关字段 -->
            <td><?php echo htmlentities($row['head']);?></td>
            <td><?php echo htmlentities($row['amount']);?></td>
        </tr>
        <?php
                $first_row = false;
            }
        }
        ?>
    </tbody>
</table>

注意事项

  1. 一定要用ORDER BY entry.id确保同凭证的记录排在一起,否则分组或对比逻辑会失效;
  2. SQL里把bank_details.Name重命名为party_name,是为了避免和entry.name变量混淆,防止输出错误;
  3. 方案二更适合正式的业务系统,视觉效果更专业,方案一适合快速实现需求。

内容的提问来源于stack exchange,提问作者chidruppa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 08:07:52