PHP+Access(PDO)合并同ID同年月员工缴费记录问题求助
解决Access表中同员工同月年记录合并及EPFee拆分问题
首先,我建议直接在SQL层面完成数据的合并与拆分操作——这比用PHP循环处理更高效、更可靠,毕竟数据库本身就擅长这类聚合计算。
最优SQL解决方案
Access支持IIF条件函数和聚合函数,我们可以用GROUP BY将同一员工、同一月份年份的记录合并,同时通过条件聚合拆分EPFee到对应字段:
SELECT `Employee ID`, MAX(`1stHalf`) AS `1stHalf`, MAX(`2ndHalf`) AS `2ndHalf`, `Month`, `Year`, SUM(IIF(`1stHalf` = 1, `EPFee`, 0)) AS `EPF1stFee`, SUM(IIF(`2ndHalf` = 1, `EPFee`, 0)) AS `EPF2ndFee` FROM `tblPAyTrans` WHERE `Employee ID` = '1011' AND `Month` = '2' AND `Year` = '2017' GROUP BY `Employee ID`, `Month`, `Year`
逻辑说明:
MAX(1stHalf):同一员工同月年的记录中,只要有一条1stHalf为1,结果就会显示1,符合你需要的合并后状态;SUM(IIF(...)):当1stHalf为1时,累加对应的EPFee,否则加0,完美实现费用拆分,没有对应记录时自动显示0.00;- 如果需要处理所有员工所有月份的记录,只需要去掉
WHERE条件即可。
修正后的PHP代码
如果一定要用PHP配合处理,下面是修正了原代码问题后的版本(依然使用上面的聚合SQL):
<?php try { // 初始化PDO连接,开启错误捕获方便调试 $db = new PDO("odbc:DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=C:\Users\User\Desktop\Demo2018.mdb; Uid=; Pwd=COMPLETEPAYROLL;"); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 使用聚合查询直接获取合并后的结果 $sql = " SELECT `Employee ID`, MAX(`1stHalf`) AS `1stHalf`, MAX(`2ndHalf`) AS `2ndHalf`, `Month`, `Year`, SUM(IIF(`1stHalf` = 1, `EPFee`, 0)) AS `EPF1stFee`, SUM(IIF(`2ndHalf` = 1, `EPFee`, 0)) AS `EPF2ndFee` FROM `tblPAyTrans` WHERE `Employee ID` = '1011' AND `Month` = '2' AND `Year` = '2017' GROUP BY `Employee ID`, `Month`, `Year` "; $result = $db->query($sql); echo "<br>RESULT: <br><br>"; echo "<table border='2'> <tr> <th>Employee ID</th> <th>1st Half</th> <th>2nd Half</th> <th>Month</th> <th>Year</th> <th>EPF1stFee</th> <th>EPF2ndFee</th> </tr>"; // GROUP BY后只会返回一条目标记录 if ($row = $result->fetch(PDO::FETCH_ASSOC)) { echo "<tr>"; echo "<td>" . htmlspecialchars($row['Employee ID']) . "</td>"; echo "<td>" . htmlspecialchars($row['1stHalf']) . "</td>"; echo "<td>" . htmlspecialchars($row['2ndHalf']) . "</td>"; echo "<td>" . htmlspecialchars($row['Month']) . "</td>"; echo "<td>" . htmlspecialchars($row['Year']) . "</td>"; echo "<td>" . number_format($row['EPF1stFee'], 2) . "</td>"; // 格式化保留两位小数 echo "<td>" . number_format($row['EPF2ndFee'], 2) . "</td>"; echo "</tr>"; } else { echo "<tr><td colspan='7'>No matching records found</td></tr>"; } echo "</table>"; } catch(PDOException $e) { echo "Database Error: " . $e->getMessage(); } // 关闭连接 $db = null; ?>
原代码的问题修正点:
- 修复了变量名错误(比如
$EP1stFee应为$EPF1stFee,$getVal['EPFee']应为$getVal1['EPFee']); - 去掉了冗余的嵌套查询,直接通过聚合SQL一次性获取结果;
- 增加了错误捕获和无记录的处理逻辑,代码更健壮;
- 使用
htmlspecialchars防止XSS注入,number_format保证费用格式统一。
内容的提问来源于stack exchange,提问作者Richmond
相关产品推荐
相关产品推荐

