2015-08-28 37 views
1

我有三個表子句:MySQL的內部聯接與右連接和多個條件WHERE全文

Meta 
Posters 
Tags 

海報對ID的多到一個關係到元。標籤對poster_id和海報有多對一的關係。

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

所以元項目可以有許多海報,而海報可以有很多標籤。

我正在嘗試創建一個SINGLE查詢,它可以接受包括特定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的情況。如果有多個樣式元素被發現是真的,因此額外的where子句補充說:

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

然後查詢時其實也有一個海報多個標籤總是返回一個空集。

如果僅使用設置爲true的單個樣式元素編寫查詢,那麼查詢將返回適當的海報。不止一個,總是返回空,而不是這種情況。

此外,還將使用TEXT搜索進行擴展。這個dosnt可以按照預期工作。

$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濾波器年 - 這將是完成

也許我在一個不正確的方式接近這一點?如果是這樣,任何建議將大大幫助

謝謝!

+0

移動WHERE Meta.year> =:降低 AND Meta.year <=:upper「;與標籤和元素的連接條件相關聯,您要求返回所有標籤,但只返回匹配的元數據。加入),所以當沒有找到匹配時,meta.year將爲空,因此評估爲false ....你有tw o選項首先將其移至連接標準,然後將其包裝在()中並添加OR(meta.year爲null)。 (將'WHERE'更改爲'ON') – xQbert

回答

2

右連接被where子句meta.year聲明否定。因此,如果標籤存在,沒有海報或元數據,它將被排除(實質上右連接被視爲INNER JOIN)。要糾正,你需要做出的元部分的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"; 
+0

第二個建議使用RIGHT連接返回NULL值,使用LEFT連接它將返回所有內容 – Dan