【问题标题】:Finding post with multiple tags查找具有多个标签的帖子
【发布时间】:2018-02-26 04:30:00
【问题描述】:

我正在搜索具有多个标签的帖子并想出了以下代码,有没有更好的方法来做到这一点或者这样可以吗?

我的 MySQL 数据库有三个表 post、tags 和 post_tags

  • 帖子:id|body
  • 标签:标签|模式
  • post_tags: postid|标签

(每个vpost上的每个标签都有自己的列)

     if(isset($_GET["query"])){
    $query = trim($_GET['query']);
    $searchs = explode(",", $query);
    $results = DB::query('SELECT * FROM post_tags WHERE tag=:tag', array(':tag' => $searchs[0]));
    $posts = "";
    foreach($results as $result){
        $pass = true;
        foreach($searchs as $search){
            if(DB::query('SELECT * FROM post_tags WHERE post_id=:postid AND 
tag=:tag', array(':postid' => $result['post_id'], ':tag' => $search))){

            }else{
                $pass = false;
                break;
            }
        }
        if($pass){
            $posts .= $result['post_id'];
        }
    }
    echo $posts;
}

我主要担心的是如果一个标签有数百万个帖子,它会不会循环数百万个听起来效率不高的东西。

编辑:

if(isset($_GET["query"])){
    $query = trim($_GET['query']);
    $searchs = explode(",", $query);
    $dataquery = "SELECT * FROM posts AS P
INNER JOIN post_tags AS PT
    ON PT.postid = P.id
INNER JOIN tags AS T
    ON PT.tag = T.tag";

    foreach($searchs as $search){
        $dataquery .= " WHERE T.tag = :tag";
    }

    $posts = DB::query($dataquery, array(':tag' => $searchs));

    echo sizeof($posts);

查询方法

     public static function query($query, $params = array()) {
    $statement = self::connect()->prepare($query);
    $statement->execute($params);
    if (explode(' ', $query)[0] == 'SELECT') {
        $data = $statement->fetchAll();
        return $data;
    }
}

【问题讨论】:

  • 是的,这就是表 JOIN 存在的原因。 dev.mysql.com/doc/refman/5.7/en/join.html 你应该只选择与你正在搜索的标签有连接的表。
  • 使用? 而不是:tag
  • 不是WHERE t = f WHERE t= d,而是WHERE t = f OR t = d
  • @ezw 我没有得到所有的字母以及你从哪里得到它们
  • 我们基本上是在告诉 MySQL 检索表 posts,但对于这个查询语句,我们将其命名为 P...因此 SELECT * FROM posts AS P跨度>

标签: php mysql


【解决方案1】:
$sql = "SELECT * FROM posts AS P
            INNER JOIN post_tags AS PT
                ON PT.postid = P.id
            INNER JOIN tags AS T
                ON PT.tag = T.tag
        WHERE " . str_repeat(" T.tag = ? AND", count($searchs));

// The actual SQL you will be using. We are removing the last ' AND' from the sql
$sql = substr($sql, 0, -4);

// The correct way
$posts = DB::query($sql, $searchs);

【讨论】:

  • 我是否将其保留为 ?还是我想用数组来替换它?
  • 我正在使用 PDO 我将我的查询方法添加到我的主要问题中,使用时页面不会加载
  • 用这个查询更新你的 PHP 实现
  • @Dan 看看我的解决方案,你是这样调用查询的吗?
【解决方案2】:

请您出示您的桌子。 或者你可以在你的表中添加关系并使用这样的查询 sql

SELECT * FROM posts p
left join post_tags pt on pt.post_id =  p.id
left join tags t on pt.tag_id = t.id
WHERE t.tag = '$searchs[0]' 

我认为像 %$searchs[0]% 这样的 t.tag 更好。如果你更多的搜索关键字,你可以使用

WHERE t.tag = '$searchs[0]' OR t.tag = '$searchs[1]'

或者你可以在帖子标题中搜索

WHERE t.tag = '$searchs[0]' OR p.post_title = '$searchs[0]'

【讨论】:

  • 搜索可以有多个标签,例如他们可能搜索“car,blue”甚至“car,blue,cheap,used” 这支持吗?还有什么是'posts p'中的p,你从哪里得到p
  • 这里的p 与我的解决方案中的P 相同。只是引用它设置代表的表的查询的名称
  • 他的查询和我的查询一样...只要添加你需要的 WHERE 子句。如果您要获得动态金额,则必须动态构建 WHERE 查询
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多