如何使用SQL查询包含关联食材的完整食谱 解决记录重复问题
问题原因
- 多表JOIN查询时,每一行结果对应一条「食谱-食材」关联关系,你原有SQL加了
GROUP BY r.r_id按食谱ID分组,只会保留每个食谱的第一条食材数据,丢失其余食材信息 - 如果你删除GROUP BY直接查询,直接逐行输出的话,又会导致同一个食谱的基础信息重复出现,每个食材对应一次重复的食谱内容
修复方案
方案1:调整查询+遍历逻辑(兼容性最好)
1. 修改SQL语句
删除不合理的GROUP BY,新增按食谱ID排序,保证同个食谱的所有食材行连续返回:
$sql = "SELECT r.r_id, r.name AS '食谱名称', r.method AS '制作步骤', ri.i_amt AS '用量', ri.i_scale AS '单位', i.i_name AS '食材名称' FROM recipes r JOIN rec_ing ri on r.r_id = ri.r_id JOIN ingredients i on i.i_id = ri.i_id ORDER BY r.r_id";
2. 修改PHP输出逻辑
新增变量记录上一个遍历的食谱ID,同一个食谱的基础信息仅输出一次,食材逐行追加:
echo "已完成的食谱"; echo "<br><br>"; $last_recipe_id = null; if ($result->num_rows > 0) { while($row = $result->fetch_assoc()) { // 检测到新的食谱时输出食谱基础信息 if ($row['r_id'] != $last_recipe_id) { // 非首个食谱先输出上一个食谱的分隔间距 if ($last_recipe_id !== null) { echo "<br><br>"; } echo "食谱名称: " . $row["食谱名称"]. "<br>制作步骤<br>" . $row["制作步骤"]."<br>食材列表:<br>"; $last_recipe_id = $row['r_id']; } // 每次循环都输出当前行的食材信息 echo "- " . $row["食材名称"]. " - 用量: " . $row["用量"]. $row["单位"]."<br>"; } } else { echo "没有查询到结果"; }
方案2:SQL层面聚合食材(性能更高)
如果你的数据库支持GROUP_CONCAT函数,可直接在查询阶段聚合同个食谱的所有食材,PHP无需额外逻辑判断:
SELECT r.name AS '食谱名称', r.method AS '制作步骤', GROUP_CONCAT(CONCAT(i.i_name, ' - ', ri.i_amt, ri.i_scale) SEPARATOR '<br>') AS '食材列表' FROM recipes r JOIN rec_ing ri on r.r_id = ri.r_id JOIN ingredients i on i.i_id = ri.i_id GROUP BY r.r_id, r.name, r.method
PHP遍历代码可直接简化为:
echo "已完成的食谱"; echo "<br><br>"; if ($result->num_rows > 0) { while($row = $result->fetch_assoc()) { echo "食谱名称: " . $row["食谱名称"]. "<br>制作步骤<br>" . $row["制作步骤"]."<br>食材列表:<br>" . $row["食材列表"] . "<br><br>"; } } else { echo "没有查询到结果"; }
内容的提问来源于stack exchange,提问作者Katia
相关产品推荐
相关产品推荐

