我有三个表:
Meta
Posters
Tags
poster在id和Meta上有多对一的关系。标签在poster_id和poster上有多对一的关系。
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);
}
只在SINGLE style元素为真时起作用。如果发现不止一个样式元素为真,因此添加了一个额外的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子句元否定。年的声明。因此,如果一个标签存在,没有海报或元数据,它将被排除(右连接实际上被视为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";