繁体   English   中英

MySQL INNER连接使用RIGHT连接和多个条件WHERE子句使用FULL TEXT

[英]MySQL INNER join with RIGHT join and multiple conditional WHERE clause with FULL TEXT

我有三个表:

Meta
Posters
Tags

海报在id与Meta之间具有多对一的关系。 标签在poster_id和Posters之间具有多对一的关系。

Meta <-- many-to-one Posters <-- many-to-one Tags

因此一个Meta项目可以有很多海报,而一个海报可以有很多标签。

我正在尝试创建一个可以接受条件过滤器(包括特定Tag类型)的单查询。

function get_filter_posters($filters, $start) {
      $query = "SELECT Meta.id, Meta.year, Posters.id AS poster_id, Posters.filename, Meta.imp_title
                FROM Meta INNER JOIN Posters ON Meta.id = Posters.movie_id
                RIGHT JOIN Tags ON Posters.id = Tags.poster_id
                WHERE Meta.year >= :lower
                AND Meta.year <= :upper ";

      foreach ($filters["genre"] as $key => $value) {
        if($value){ $query .= " AND Meta.genre = '".$key."' "; }
      }

      foreach ($filters["style"] as $key => $value) {
        if($value){ $query .= " AND Tags.tag = '".$key."' "; }
      }

      $query .= "ORDER BY Meta.year DESC
                 LIMIT :start,:limit";

      $statement = $this->db->prepare($query);
      $statement->bindParam(':limit', $this->limit, PDO::PARAM_INT);
      $statement->bindParam(':start', $start, PDO::PARAM_INT);
      $statement->bindParam(':lower', $filters["year_range"][0], PDO::PARAM_INT);
      $statement->bindParam(':upper', $filters["year_range"][1], PDO::PARAM_INT);
      $statement->execute();
      return $statement->fetchAll(PDO::FETCH_ASSOC);
 }

这仅在单个样式元素为true时有效。 如果发现多个样式元素为true,因此添加了附加的where子句:

      foreach ($filters["style"] as $key => $value) {
        if($value){ $query .= " AND Tags.tag = '".$key."' "; }
      }

那么实际上只有一个带有多个标签的海报时,查询总是返回一个空集。

如果编写查询时仅将一个样式元素设置为true,则该查询将返回正确的发布者。 不止一个,总是返回空,事实并非如此。

也将通过TEXT搜索进行扩展。 这项工作完全符合预期。

$query = "SELECT Meta.id, Meta.year, Posters.id AS poster_id, Posters.filename, Meta.imp_title,
              MATCH(".$search_type.") AGAINST($term) AS Relevance
              FROM Meta INNER JOIN Posters ON Meta.id = Posters.movie_id
              RIGHT JOIN Tags ON Posters.id = Tags.poster_id
              WHERE MATCH(".$search_type.")
              AGAINST($term IN BOOLEAN MODE)";

      foreach ($filters["genre"] as $key => $value) {
        if($value){ $query .= " AND Meta.genre = '".$key."' "; }
      }

      foreach ($filters["style"] as $key => $value) {
        if($value){ $query .= " AND Tags.tag = '".$key."' "; }
      }

      $query .= "AND Meta.year >= ".$filters["year_range"][0]."
                 AND Meta.year <= ".$filters["year_range"][1]."
                 ORDER BY Relevance + Meta.year DESC
                 LIMIT :start,:limit";

      $statement = $this->db->prepare($query);
      $statement->bindParam(':start', $start, PDO::PARAM_INT);
      $statement->bindParam(':limit', $this->limit, PDO::PARAM_INT);
      $statement->execute();
      return $statement->fetchAll(PDO::FETCH_ASSOC);

忽略我没有bindParam过滤器年份的事实-它将完成

也许我以不正确的方式处理此问题? 如果是这样,任何建议将极大地帮助您

谢谢!

正确的联接被where子句meta.year语句否定。 因此,如果存在一个没有张贴者或元数据的标签,则该标签被排除(实质上,正确的连接被视为“内部连接”)。 要更正,您需要在海报级别或标记右连接上对连接的meta部分进行where子句限制...

也许

  $query = "SELECT Meta.id, Meta.year, Posters.id AS poster_id, Posters.filename, Meta.imp_title
            FROM Meta 
            INNER JOIN Posters ON Meta.id = Posters.movie_id
            RIGHT JOIN Tags ON Posters.id = Tags.poster_id
             ON Meta.year >= :lower
            AND Meta.year <= :upper ";

要么

  $query = "SELECT Meta.id, Meta.year, Posters.id AS poster_id, Posters.filename, Meta.imp_title
            FROM Meta INNER JOIN Posters 
              ON Meta.id = Posters.movie_id
             AND Meta.year >= :lower
             AND Meta.year <= :upper
            RIGHT JOIN Tags ON Posters.id = Tags.poster_id";

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM