【问题标题】:mysql php, filter on multiple columns with a combination of LIKE and =mysql php,使用LIKE和=的组合过滤多个列
【发布时间】:2015-12-12 15:10:33
【问题描述】:

我正在尝试从包含 5 个字段的表单中搜索员工表。用户可以使用具有以下规则的任何或所有搜索字段:

USERFORM (html/php)
EID: (textbox, exact match)
First name: (textbox, LIKE %fname%)
Last Name: (textbox, LIKE %lname%)
Email: (textbox, LIKE %email%)
Department: (dropdown, exact match)(includes a default value for not selecting amongst <options>)

我遇到的问题是,当我搜索 firstname = %j% 时,它会正确过滤所有名字包含 j 的员工。但是,每当我将其与另一个或多个搜索参数结合使用时,它会带来最大数量的结果,而不是过滤后的最小值,例如 firstname %j%, lastname, %b%。仍会返回Joe bloggs, and joe coggs

就像我要在那里添加一个部门一样,我希望它给我一个名字中有 j,姓有 b 的人,他们是部门 1 的成员。但相反,它会给me 该部门中的所有员工(无论名称搜索参数如何),以及其他部门中的员工 bu 他们的姓名中有 j。

这里是查询和其他代码:

    $eid = $_POST['eid'];
    $p_fname = $_POST['fname'];
    $p_lname = $_POST['lname'];
    $p_email = $_POST['email'];
    $depid = $_POST['depid'];
        if(empty($_POST['fname'])) { $fname = "";} else { $fname = "%$p_fname%"; }
        if(empty($_POST['lname'])) { $lname = "";} else { $lname = "%$p_lname%"; }
        if(empty($_POST['email'])) { $email = "";} else { $email = "%$p_email%"; }


    $query = $db->prepare("SELECT `employees`.`eid`, `employees`.`fname`, `employees`.`lname`, `employees`.`dob`, `employees`.`email`, `departments`.`depname` 
        FROM `employees` 
        INNER JOIN `departments` 
        ON `employees`.`depid` = `departments`.`id` 
        WHERE 
            `eid` = :eid || 
            `fname` LIKE :fname || 
            `lname` LIKE :lname || 
            `email` LIKE :email || 
            `depid` = :depid 
        ORDER BY `employees`.`eid` ASC 
        LIMIT :start_from, 10");
    $query->bindParam(":eid", $eid);
    $query->bindParam(":fname", $fname);
    $query->bindParam(":lname", $lname);
    $query->bindParam(":email", $email);
    $query->bindParam(":depid", $depid);
    $query->bindParam(":start_from", $start_from);
    $query->execute();

当我想到它时,我明白为什么它会返回最大结果,但是我尝试将 OR 更改为 AND 并使用括号我根本没有得到任何结果,因为查询试图返回具有未定义的列中的空白值。

编辑:: 我也试过用 AND 表示确切的值,用 OR 表示通配符值,这会返回所有结果。

我真的不想编写一个 php 脚本,它必须定义要使用的列并为每个场景执行不同的查询。

【问题讨论】:

  • 如果需要满足多个条件,使用 AND 而不是 OR
  • 请阅读我的编辑。我已经尝试使用 AND 而不是 OR 带括号和不带括号。这返回了 0 条记录,可能是因为它试图在未选择该列时过滤没有值的列。我还尝试将参数值更改为%(如果未在搜索中使用)以及使用 AND。这也没有给我我需要的结果。

标签: php mysql pdo


【解决方案1】:

我解决了这个问题,方法是使用LIKE 而不是= 作为运算符,并将OR 换成AND,如问题评论中所述。

我必须使用LIKE 的原因是,当表单中的字段未使用时,它必须是通配符,因此 = 不合适。

$p_eid = $_POST['eid'];
    $p_fname = $_POST['fname'];
    $p_lname = $_POST['lname'];
    $p_email = $_POST['email'];
    $p_depid = $_POST['depid'];
        // wildcard added when field not in use, but removed when in use
        if(empty($_POST['eid'])) { $eid = "%%";} else { $eid = "$p_eid"; }
        if(empty($_POST['fname'])) { $fname = "%%";} else { $fname = "%$p_fname%"; }
        if(empty($_POST['lname'])) { $lname = "%%";} else { $lname = "%$p_lname%"; }
        if(empty($_POST['email'])) { $email = "%%";} else { $email = "%$p_email%"; }
        // wildcard added when field not in use, bu removed when in use
        if(empty($_POST['depid'])) { $depid = "%%";} else { $depid = "$p_depid"; }

    $query = $db->prepare("SELECT `employees`.`eid`, `employees`.`fname`, `employees`.`lname`, `employees`.`dob`, `employees`.`email`, `departments`.`depname` 
        FROM `employees` 
        INNER JOIN `departments` 
        ON `employees`.`depid` = `departments`.`id` 
        WHERE 
            `eid` LIKE :eid AND    
            `fname` LIKE :fname AND  
            `lname` LIKE :lname AND  
            `email` LIKE :email AND  
            `depid` LIKE :depid
        ORDER BY `employees`.`eid` ASC 
        LIMIT :start_from, 10");
    $query->bindParam(":eid", $eid);
    $query->bindParam(":fname", $fname);
    $query->bindParam(":lname", $lname);
    $query->bindParam(":email", $email);
    $query->bindParam(":depid", $depid);
    $query->bindParam(":start_from", $start_from);
    $query->execute();

【讨论】:

    【解决方案2】:

    我建议不要在 WHERE 子句中添加不必要的逻辑。构建动态语句并将变量传递到 execute() 调用

    $conditions = [];
    $params = [];
    if (!empty($_POST['eid']) {
        $conditions[] = "eid = ?";
        $params[] = $_POST['eid'];
    }
    if (!empty($_POST['fname']) {
        $conditions[] = "fname LIKE ?";
        $params[] = $_POST['fname'];
    }
    if (!empty($_POST['lname']) {
        $conditions[] = "lname LIKE ?";
        $params[] = $_POST['lname'];
    }
    if (!empty($_POST['email']) {
        $conditions[] = "email LIKE ?";
        $params[] = $_POST['email'];
    }
    if (!empty($_POST['depid']) {
        $conditions[] = "depid = ?";
        $params[] = $_POST['depid'];
    }
    $params[] = $start_from;
    

    然后将条件应用于 sql 字符串,并使用绑定到占位符的值执行准备好的语句。

    $sql = "SELECT employees.eid,
                   employees.fname,
                   employees.lname,
                   employees.dob,
                   employees.email,
                   departments.depname
            FROM employees 
            INNER JOIN departments ON employees.depid = departments.id
            " . ($conditions ? 'WHERE ' . implode(" AND ", $conditions) : '') . "
            ORDER BY employees.eid 
            LIMIT ?, 10";
    $query = $db->prepare($sql);
    $query->execute($params);
    

    【讨论】:

      猜你喜欢
      • 2018-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-31
      • 1970-01-01
      • 1970-01-01
      • 2017-08-17
      • 1970-01-01
      相关资源
      最近更新 更多