PHP和子句不显示结果,但显示OR

PHP和子句不显示结果,但显示OR,php,mysql,sql,database,phpmyadmin,Php,Mysql,Sql,Database,Phpmyadmin,我有一个图书搜索,它正在搜索我正在寻找的书籍,它搜索的书籍共享作者类别或出版商。我已经设置了它,它适用于OR子句,例如,有一个类别的书籍儿童或与他们相关的历史,这是正确的,但当我搜索属于两个类别(和)的书籍时,例如儿童和魔法(哈利波特),它不会显示这些书籍,即使它们在数据库中链接。 以上是我使用或搜索属于儿童和历史的书籍时所做的搜索 上面你们可以看到,当哈利波特的书确实属于这两本书时,我并没有得到关于分享儿童和魔法的书的结果。 上面是数据库中的链接,它为每本书提供了它们的分类,Magic是

我有一个图书搜索,它正在搜索我正在寻找的书籍,它搜索的书籍共享作者类别或出版商。我已经设置了它,它适用于OR子句,例如,有一个类别的书籍儿童或与他们相关的历史,这是正确的,但当我搜索属于两个类别(和)的书籍时,例如儿童和魔法(哈利波特),它不会显示这些书籍,即使它们在数据库中链接。

以上是我使用或搜索属于儿童和历史的书籍时所做的搜索

上面你们可以看到,当哈利波特的书确实属于这两本书时,我并没有得到关于分享儿童和魔法的书的结果。 上面是数据库中的链接,它为每本书提供了它们的分类,Magic是分类1,Childrens是分类2,你可以看到它们都共享这些

下面是该查询的PHP代码

<?php
include 'header.php';
include 'searchscriptTEST.php';

$sql =  "SELECT DISTINCT bk.title AS Title, bk.bookid AS BookID, bk.year AS Year, bk.publisher AS Publisher, aut.authorname AS Author 
         FROM book bk 

         JOIN book_category bk_cat 
         ON bk_cat.book_id = bk.bookid

         JOIN categories cat 
         ON cat.id = bk_cat.category_id

         JOIN books_authors bk_aut 
         ON bk_aut.book_id = bk.bookid

         JOIN authors aut
         ON aut.id = bk_aut.author_id";

if(isset($_GET['searchInput'])){
$input = $_GET['searchInput'];
$input = preg_replace('/[^A-Za-z0-9]/', '', $input);
}
if (isset($input)){

    $getters = array();
    $queries = array();

    foreach ($_GET as $key => $value) {
        $temp = is_array($value) ? $value : trim($value);
        if (!empty($temp)){
        if (!in_array($key, $getters)){
            $getters[$key] = $value;
            }
        }
    }

    if (!empty($getters)) {

        foreach($getters as $key => $value){
            //${$key} = $value;
            switch ($key) {
                case 'searchInput':
                    array_push($queries,"(bk.title LIKE '%{$getters['searchInput']}%' 
                    || bk.description LIKE '%{$getters['searchInput']}%' || bk.isbn LIKE '%{$getters['searchInput']}%' 
                    || bk.keywords LIKE '%{$getters['searchInput']}%' || aut.authorname LIKE '%{$getters['searchInput']}%')");
                break;
                case 'srch_publisher':
                    array_push($queries, "(bk.publisher = '{$getters["srch_publisher"]}')");
                break;
                case 'Year':
                    if(isset($getters['Year1']) ==""){
                        array_push($queries, "(bk.year = '{$getters['Year']}')");
                    } else {
                        array_push($queries, "(bk.year BETWEEN '$value' AND '{$getters['Year1']}')");
                    }
                break;
                case 'srch_author':
                     if(isset($getters['authorOperator']) ==""){
                    array_push($queries, "(bk_aut.author_id = '{$getters["srch_author"]}')");
                    } else {
                        $operator = $getters['authorOperator'];
                        array_push($queries, "(bk_aut.author_id = '$value' $operator bk_aut.author_id = '{$getters['srch_author1']}')");
                    }
                break;
                case 'srch_category':
                     if(isset($getters['catOperator']) ==""){
                        array_push($queries, "(bk_cat.category_id = '{$getters["srch_category"]}')");
                    } else {
                        $operator1 = $getters['catOperator'];
                        array_push($queries, "(bk_cat.category_id = '$value' $operator1 bk_cat.category_id = '{$getters['srch_category1']}')");
                    }
                break;

        }
    }
}
if(!empty($queries)){
    $sql .= " WHERE ";
    $i = 1;
    foreach ($queries as $query) {
        if($i < count($queries)){
            $sql .= $query." AND ";
        } else {
            $sql .= $query;
        }   
        $i++;
    }
}
$sql .= " GROUP BY bk.title ORDER BY bk.title ASC";
var_dump($sql);

}else{
    $sql .= " GROUP BY bk.title ORDER BY bk.title ASC";
}


$rs = mysql_query($sql) or die(mysql_error());
$rows = mysql_fetch_assoc($rs);
$tot_rows = mysql_num_rows($rs);
?>

在格式化查询以使其实际可读后,您将看到以下行:

bk_cat.category_id = '2' AND bk_cat.category_id = '1'
这样不行,
category\u id
不能同时是
2
1

您的查询应该类似于:

SELECT books.*
FROM books
  JOIN book_categories bc1 ON books.id = bc1.book_id AND bc1.category_id = 1
  JOIN book_categories bc2 ON books.id = bc2.book_id AND bc1.category_id = 2

您需要在类别上加入两次,或者在需要匹配的类别上加入两次。

在格式化查询以使其实际可读后,您会看到以下行:

bk_cat.category_id = '2' AND bk_cat.category_id = '1'
这样不行,
category\u id
不能同时是
2
1

您的查询应该类似于:

SELECT books.*
FROM books
  JOIN book_categories bc1 ON books.id = bc1.book_id AND bc1.category_id = 1
  JOIN book_categories bc2 ON books.id = bc2.book_id AND bc1.category_id = 2

您需要在类别上加入两次
JOIN
,或者加入的次数与您要匹配的类别相同。

有多种方法可以做到这一点,但最简单的方法是使用
WHERE
子句(类似于这样的子句)来选择属于多个类别的
书籍:

WHERE
        `bk`.`book_id` IN (SELECT `book_id` FROM `book_category` WHERE `category_id` = '2')
    AND `bk`.`book_id` IN (SELECT `book_id` FROM `book_category` WHERE `category_id` = '1')

有多种方法可以做到这一点,但最简单的方法是使用类似这样的
WHERE
子句来
选择属于多个类别的书籍:

WHERE
        `bk`.`book_id` IN (SELECT `book_id` FROM `book_category` WHERE `category_id` = '2')
    AND `bk`.`book_id` IN (SELECT `book_id` FROM `book_category` WHERE `category_id` = '1')

我认为这是可行的,但效率很低。现在,您强制MySQL始终选择一个类别中的所有书籍。它无法进行优化。@doge Correct这在较大的结果集上可能会变得效率低下。对于较小的结果集,可读性很好。@AeroX yes u legend有效,我将测试它的作者和发布者,但我相信它会很好,谢谢:D@Doge我刚刚在生产环境MS-SQL Server上做了一个测试,从类似的查询中得到的查询计划会导致
嵌套循环(内部连接)
。我假设MySQL查询规划器选择做类似的事情(不过我目前没有访问MySQL服务器的权限来测试这一点)。您可以运行
EXPLAIN[query]
了解运行查询需要做些什么。我认为这是可行的,但效率很低。现在你强迫MySQL总是选择一个类别中的所有书籍。它无法优化。@doge Correct这在较大的结果集上可能会变得效率低下。但对于较小的结果集,可读性很好。@AeroX yes u lege我会测试它的作者和出版商,但我相信它会很好地工作。谢谢:D@Doge我刚刚在生产环境MS-SQL Server上做了一个测试,从类似的查询中得到的查询计划会导致
嵌套循环(内部联接)
。我假设MySQL查询规划器选择做类似的事情(不过我目前没有访问MySQL服务器的权限来测试这个问题)。您可以运行
EXPLAIN[query]
了解运行查询需要做什么。我没有了解$operator1在数组推送函数中扮演的角色我没有了解$operator1在数组推送函数中扮演的角色