PHP如何通过TAGS表关键词搜索获取对应去重的POSTS表内容
解决方案
推荐优先使用联表一次性查询的方案,性能更高、逻辑更简洁。
方案1:单次SQL联表查询(最优选择)
直接通过JOIN关联两张表,同时用DISTINCT实现去重,一次查询就能拿到所有需要的文章数据,不需要分两次查询。
注意:你原代码中SQL写错了标签字段名,TAGS表的标签字段是
tags,不是tag,下面代码已经修正。
$stmt = $db->prepare(" SELECT DISTINCT p.title, p.content, p.post_id FROM tags t INNER JOIN posts p ON t.related_to = p.post_id WHERE t.tags LIKE ? COLLATE utf8_general_ci "); $stmt->execute(["%$value%"]); $posts = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($posts) { foreach ($posts as $post) { // 按要求格式输出 echo "{$post['title']} - {$post['content']} ({$post['post_id']})<br>"; } }
逻辑说明
INNER JOIN基于related_to和post_id的关联关系匹配标签表和文章表DISTINCT自动过滤重复的文章记录,哪怕一篇文章有多个匹配到的标签,也只会返回一次- 不需要额外处理去重、二次查询,性能更高
方案2:先拿去重的文章ID再查询(适合需要单独用到ID列表的场景)
如果你确实需要先获取去重的关联ID列表,再单独查询文章表,可以用下面的方法:
步骤1:获取去重的文章ID
方式A:SQL层面直接去重(推荐)
$stmt = $db->prepare("SELECT DISTINCT related_to FROM tags WHERE tags LIKE ? COLLATE utf8_general_ci"); $stmt->execute(["%$value%"]); $postIds = $stmt->fetchAll(PDO::FETCH_COLUMN, 0); // 直接将第一列转为一维数组 if (empty($postIds)) { // 无匹配结果直接终止逻辑 return; }
方式B:PHP层面去重(不改原查询逻辑的场景)
如果你不想修改原查询语句,也可以对查询结果用PHP函数去重:
// 你原有的查询逻辑拿到$show后 $postIds = array_unique(array_column($show, 'related_to'));
步骤2:根据ID列表查询文章表
// 构造IN查询的占位符,避免SQL注入风险 $placeholders = rtrim(str_repeat('?,', count($postIds)), ','); $stmt = $db->prepare("SELECT title, content, post_id FROM posts WHERE post_id IN ($placeholders)"); $stmt->execute($postIds); $posts = $stmt->fetchAll(PDO::FETCH_ASSOC); // 输出逻辑和方案1一致 foreach ($posts as $post) { echo "{$post['title']} - {$post['content']} ({$post['post_id']})<br>"; }
内容的提问来源于stack exchange,提问作者Deniz Şafak
相关产品推荐
相关产品推荐

