如何在PHP中仅查询存在关联子表数据的父表记录?
嘿,这个需求很常见,我来给你梳理几种靠谱的实现方式,核心是先写对SQL语句,再结合PHP执行就行~
方法1:使用INNER JOIN(推荐,性能优异)
INNER JOIN的特性就是只保留两张表中匹配成功的记录,刚好符合你“只查询有关联Items数据的CATEGORY”的需求,而且当Items表的ct_id字段有索引时,执行速度会非常快。
对应的SQL语句
SELECT c.ct_id, c.ct_name FROM CATEGORY c INNER JOIN Items i ON c.ct_id = i.ct_id GROUP BY c.ct_id, c.ct_name
这里加GROUP BY是为了避免同一个分类因为关联多个商品而被重复返回。
PHP代码实现(PDO版,安全且通用)
<?php // 替换成你的数据库连接信息 $dbHost = 'localhost'; $dbName = 'your_database_name'; $dbUser = 'your_username'; $dbPass = 'your_password'; try { // 初始化PDO连接 $pdo = new PDO( "mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] ); // 准备并执行SQL $sql = "SELECT c.ct_id, c.ct_name FROM CATEGORY c INNER JOIN Items i ON c.ct_id = i.ct_id GROUP BY c.ct_id, c.ct_name"; $stmt = $pdo->prepare($sql); $stmt->execute(); // 获取所有符合条件的分类数据 $validCategories = $stmt->fetchAll(PDO::FETCH_ASSOC); // 示例:遍历输出结果 foreach ($validCategories as $category) { echo "分类ID: {$category['ct_id']},分类名称: {$category['ct_name']}<br>"; } } catch (PDOException $e) { echo "数据库操作出错: " . $e->getMessage(); } ?>
方法2:使用EXISTS子查询(逻辑更直观)
EXISTS子查询会检查是否存在至少一条匹配的Items记录,只要存在就返回对应的CATEGORY记录。这种写法逻辑清晰,在子表数据量较大时,性能往往比IN子查询更好。
对应的SQL语句
SELECT ct_id, ct_name FROM CATEGORY c WHERE EXISTS (SELECT 1 FROM Items i WHERE i.ct_id = c.ct_id)
PHP代码实现(PDO版)
<?php $dbHost = 'localhost'; $dbName = 'your_database_name'; $dbUser = 'your_username'; $dbPass = 'your_password'; try { $pdo = new PDO( "mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] ); $sql = "SELECT ct_id, ct_name FROM CATEGORY c WHERE EXISTS (SELECT 1 FROM Items i WHERE i.ct_id = c.ct_id)"; $stmt = $pdo->prepare($sql); $stmt->execute(); $validCategories = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($validCategories as $category) { echo "分类ID: {$category['ct_id']},分类名称: {$category['ct_name']}<br>"; } } catch (PDOException $e) { echo "数据库操作出错: " . $e->getMessage(); } ?>
方法3:使用IN子查询(写法简单)
这种方式先从Items表中取出所有存在的分类ID,再用这些ID过滤CATEGORY表。写法简单易懂,但如果Items表的ct_id数量很大,性能可能不如前两种方法。
对应的SQL语句
SELECT ct_id, ct_name FROM CATEGORY WHERE ct_id IN (SELECT DISTINCT ct_id FROM Items)
这里加DISTINCT是为了减少子查询返回的重复ID,优化查询效率。
额外提示
- 优先选择
INNER JOIN或EXISTS,它们的执行效率更稳定,适合大部分场景。 - 一定要给
Items表的ct_id字段添加索引,这会大幅提升关联查询的速度。 - 如果你习惯用mysqli扩展,写法类似,只需要把PDO的相关函数替换成mysqli的对应函数(比如
mysqli_prepare、mysqli_stmt_execute等)即可。
内容的提问来源于stack exchange,提问作者DuliNini
相关产品推荐
相关产品推荐

