如何合并PHP中LEFT JOIN查询与IF ELSE逻辑实现点赞状态判断
合并查询获取产品点赞数据与用户点赞状态
我来帮你把原本需要分开执行的两个查询合并成一个高效的SQL语句,一次性拿到你需要的所有数据,不用再做两次数据库请求啦!
核心思路
通过LEFT JOIN关联Products表和CustomerProducts表,在关联条件里同时匹配产品ID和当前用户ID,再用CASE语句直接判断用户是否点赞了对应产品,最终一次性返回productID、numOfLikes和isLiked三个字段。
完整实现步骤
1. 处理前端传入的数据
首先解析前端发送的JSON数据,提取用户ID和产品ID数组,并确保所有ID都是整数类型(避免SQL注入风险):
// 解析请求中的JSON数据 $requestData = json_decode(file_get_contents('php://input'), true); // 提取并格式化用户ID $customerID = intval($requestData['customerId']); // 从产品ID数组中提取纯数字ID $productIds = array_map(function($item) { return intval($item['productId']); }, $requestData['gArrayOfProductIds']);
2. 合并后的SQL查询代码
这里提供两种实现方式,优先推荐更安全的预处理语句版本:
基础拼接版(已做安全处理)
$sql = "SELECT p.productID, p.numOfLikes, CASE WHEN cp.customerID IS NULL THEN 'false' ELSE 'true' END AS isLiked FROM Products p LEFT JOIN CustomerProducts cp ON cp.productID = p.productID AND cp.customerID = " . $customerID . " WHERE p.productID IN (" . implode(", ", $productIds) . ")"; $result = $connection->query($sql);
更安全的预处理语句版(推荐)
// 生成IN子句的占位符,比如"?, ?, ?, ?" $placeholders = implode(',', array_fill(0, count($productIds), '?')); $sql = "SELECT p.productID, p.numOfLikes, CASE WHEN cp.customerID IS NULL THEN 'false' ELSE 'true' END AS isLiked FROM Products p LEFT JOIN CustomerProducts cp ON cp.productID = p.productID AND cp.customerID = ? WHERE p.productID IN (" . $placeholders . ")"; // 初始化预处理语句 $stmt = $connection->prepare($sql); // 绑定参数:第一个参数是用户ID,后面是所有产品ID $params = array_merge([$customerID], $productIds); // 生成参数类型字符串(所有参数都是整数,所以用多个"i") $types = str_repeat('i', count($params)); // 绑定并执行查询 $stmt->bind_param($types, ...$params); $stmt->execute(); // 获取查询结果 $result = $stmt->get_result();
逻辑说明
- LEFT JOIN的作用:确保所有你指定的产品ID都会被返回,哪怕用户没有点赞该产品(此时
CustomerProducts表的对应字段会为NULL)。 - CASE语句判断点赞状态:如果
cp.customerID为NULL,说明当前用户没有点赞该产品,返回'false';否则返回'true',字段命名为isLiked。 - 安全处理:无论是用
intval转换参数,还是使用预处理语句,都是为了避免SQL注入攻击,预处理语句是更推荐的安全做法。
内容的提问来源于stack exchange,提问作者Ariel Estrin
相关产品推荐
相关产品推荐

