如何在表格行中合并显示两个数据库表的费用与收款记录并解决重复值问题
嘿,我帮你梳理下这个问题,咱们一步步解决它!
首先,你当前的代码是分别循环expenses和recive_payment两个表,所以会先显示所有费用记录,再显示所有收款记录,没法混合排序。而合并后出现重复值,大概率是因为查询逻辑没处理好,或者重复连接数据库导致的问题。下面是具体的解决方案:
核心思路:合并查询+统一循环
把两个表的记录通过SQL的UNION ALL合并成一个结果集,按日期排序后再循环显示,这样就能让费用和收款记录按时间顺序依次上下排列,同时避免重复查询和重复值问题。
修正后的完整代码
<?php // 只连接一次数据库,避免重复引入导致的问题 require '../Database/conn.php'; // 使用预处理语句,防止SQL注入(非常重要!) $stmt = mysqli_prepare($conn, " SELECT date, type, total, 'expense' AS record_type -- 标记这条记录是费用 FROM expenses WHERE payee LIKE ? UNION ALL -- 合并两个表的记录,保留所有行 SELECT date, type, total, 'payment' AS record_type -- 标记这条记录是收款 FROM recive_payment WHERE customer LIKE ? ORDER BY date ASC -- 按日期排序,让记录按时间顺序显示 "); // 绑定参数,替换SQL中的?,两个?对应两个$value mysqli_stmt_bind_param($stmt, "ss", $value, $value); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); ?> <!-- 确保tr在正确的table容器中,原代码div包裹tr不符合HTML规范 --> <table> <tbody> <?php while($fetch = mysqli_fetch_array($result)) { // 根据记录类型判断金额前缀 $amountPrefix = $fetch['record_type'] === 'expense' ? 'R-' : 'R'; ?> <tr> <td class="date"> <h6 class="mb-0 text-sm date"><?php echo substr($fetch['date'], 0, 100);?></h6> </td> <td class="date"> <h6 class="mb-0 text-sm date"></h6> <!-- 保留你原代码的空单元格 --> </td> <td class="type"> <h6 class="mb-0 text-sm type"><?php echo substr($fetch['type'], 0, 100);?></h6> </td> <td class="total"> <h6 class="mb-0 text-sm total"><?php echo $amountPrefix . substr($fetch['total'], 0, 100);?></h6> </td> </tr> <?php } ?> </tbody> </table>
关键优化点说明
- 合并查询:用
UNION ALL把两个表的记录合并,添加record_type字段区分费用/收款,确保字段数量和类型一致,这样能统一处理显示逻辑。 - 按日期排序:添加
ORDER BY date ASC,让所有记录按时间顺序排列,而不是先显示完一类再显示另一类。 - SQL注入防护:替换直接拼接
$value的写法,用预处理语句绑定参数,避免安全风险。 - 修复HTML结构:原代码中
<div>直接包裹<tr>不符合HTML规范,改成用<table>和<tbody>包裹表格行,避免布局问题。 - 单次数据库连接:只引入一次
conn.php,避免重复连接或变量冲突。
解决重复值问题
如果还是出现重复记录,你可以:
- 检查
expenses和recive_payment表中是否存在完全相同的date、type、total记录; - 若不需要保留重复记录,把
UNION ALL改成UNION(它会自动去重,但注意UNION会影响性能,尽量确认数据是否真的需要去重); - 确认
$value变量的取值是否正确,避免查询范围过大导致的重复。
内容的提问来源于stack exchange,提问作者Pierre
相关产品推荐
相关产品推荐

