如何在foreach循环中显示SQL COUNT的统计结果
解决方案
你的问题根源在于当前统计预订数的SQL是全局固定日期的统计,没有和循环中的单个课程关联,同时硬编码了日期值,导致所有课程显示相同的结果。下面给出两种解决方法,优先推荐第一种(性能更优):
方法一:合并查询,一次获取所有课程及对应预订数
直接修改主查询,通过LEFT JOIN关联预订表,同时按课程分组统计对应日期的预订数,避免多次数据库查询:
<?php $total_pages = ceil($total_rows / $no_of_records_per_page); // 修改主SQL,关联预订表并统计每个课程的预订数 $sql = "SELECT c.*, COUNT(b.ClassID) as Anzahl FROM tblclasses c LEFT JOIN tblbooking b ON c.ID = b.ClassID AND b.DatumZeit LIKE CONCAT('%', DATE_FORMAT(c.DatumZeit, '%d.%m.%Y'), '%') GROUP BY c.ID LIMIT $offset, $no_of_records_per_page"; $query = $dbh->prepare($sql); $query->execute(); $results = $query->fetchAll(PDO::FETCH_OBJ); $cnt=1; if($query->rowCount() > 0) { foreach($results as $row) {?> <div class="col-md-4"> <div class="classes-item-warp"> <div class="classes-item"> <!-- <div class="ci-img"> <img src="admin/images/<?php echo $row->Titelbild;?>" alt=""> </div> --> <div class="ci-text"> <h4><a href="classes-details.php?viewid=<?php echo $row->ID;?>"><?php echo $row->TypeofClasses;?></a></h4> <p>Datum und Uhrzeit:</p> <p><?php echo $row->DatumZeit;?></p> <p>-----------</p> <!-- 直接使用主查询返回的Anzahl字段 --> <p><?php echo $row->Anzahl;?></p> </div> <div class="ci-bottom"> <div class="ci-author"> <img src="admin/images/<?php echo $row->ProfilePics;?>" alt=""> <div class="author-text"> <h6><?php echo $row->Trainer;?></h6> <p>Dauer: <?php echo $row->Dauer;?></p> </div> </div> <a href="book-yoga-sesion.php?cid=<?php echo $row->ID;?>" class="site-btn sb-gradient">Buchen</a> </div> </div> </div> </div> <?php } } ?>
逻辑说明:
LEFT JOIN保证即使课程没有任何预订,也能正常显示(此时Anzahl为0)CONCAT('%', DATE_FORMAT(c.DatumZeit, '%d.%m.%Y'), '%')自动提取当前课程的日期,匹配预订表中对应日期的记录COUNT(b.ClassID)仅统计关联到的有效预订记录(避免统计NULL值)
方法二:循环内动态查询(性能略差,仅适合课程数量少的场景)
如果无法修改主查询,可以在循环中针对每个课程单独查询预订数,注意使用预处理语句防止SQL注入:
<?php $total_pages = ceil($total_rows / $no_of_records_per_page); $sql="SELECT * from tblclasses LIMIT $offset, $no_of_records_per_page"; $query = $dbh->prepare($sql); $query->execute(); $results=$query->fetchAll(PDO::FETCH_OBJ); $cnt=1; if($query->rowCount() > 0) { foreach($results as $row) { // 针对当前课程和日期查询预订数 $anzahlSql = "SELECT COUNT(*) as Anzahl FROM tblbooking WHERE ClassID = ? AND DatumZeit LIKE CONCAT('%', DATE_FORMAT(?, '%d.%m.%Y'), '%')"; $stmt = $dbh->prepare($anzahlSql); $stmt->execute([$row->ID, $row->DatumZeit]); $bookingCount = $stmt->fetch()['Anzahl']; ?> <div class="col-md-4"> <div class="classes-item-warp"> <div class="classes-item"> <!-- <div class="ci-img"> <img src="admin/images/<?php echo $row->Titelbild;?>" alt=""> </div> --> <div class="ci-text"> <h4><a href="classes-details.php?viewid=<?php echo $row->ID;?>"><?php echo $row->TypeofClasses;?></a></h4> <p>Datum und Uhrzeit:</p> <p><?php echo $row->DatumZeit;?></p> <p>-----------</p> <p><?php echo $bookingCount;?></p> </div> <div class="ci-bottom"> <div class="ci-author"> <img src="admin/images/<?php echo $row->ProfilePics;?>" alt=""> <div class="author-text"> <h6><?php echo $row->Trainer;?></h6> <p>Dauer: <?php echo $row->Dauer;?></p> </div> </div> <a href="book-yoga-sesion.php?cid=<?php echo $row->ID;?>" class="site-btn sb-gradient">Buchen</a> </div> </div> </div> </div> <?php } } ?>
注意事项:
- 这种方式会产生N+1次数据库查询(N为课程数量),如果课程较多会影响性能,优先选择方法一
- 使用预处理语句
?占位符,避免SQL注入风险
内容的提问来源于stack exchange,提问作者Uros Dobricic
相关产品推荐
相关产品推荐

