使用选择(高级)过滤数据

时间:2018-05-03 20:23:14

标签: php html mysql filter

我参与了一个项目,我有三种过滤器可能性。按名称,城市和省份过滤。现在,我正在做的是简单的IF试图考虑所有可能性。

示例:它可以是[名称] [城市] [全部]或[全部] [城市] [省]或[全部] [全部] [省],它总共有8到9种可能性。这意味着如果我的PHP代码中有大约8个条件试图捕获所有内容。

所以我的问题是:在MySql上有没有办法做一个SELECT data1 .. FROM tableName WHERE ...但是当我不提供例如城市时它只搜索名称和省份。

3 个答案:

答案 0 :(得分:0)

有几种方法。一种方法是动态构建SQL文本。如果选项是离散的,我们可以单独处理每个条件,包括或不包括。作为模式的一个例子:

启动SQL文本:

  $sql = "SELECT ...
            FROM ... 
           WHERE 1=1 ";

有条件地附加搜索条件

  if(  we need to add a condition on city ) {
       $sql .= " AND t.city LIKE :city ";
  }
  if(  we need to add a condition on province ) {
       $sql .= " AND t.province LIKE :province ";
  }
  if(  we need to add a condition on name  ) {
       $sql .= " AND t.name LIKE :name ";
  }

完成SQL文本

  $sql .= " ORDER BY ..."; 

准备SQL文本(这里是回显/ var_dump / log $ sql内容进行调试的好地方)

  $sth = $dbh->prepare($sql);

有条件地绑定我们添加的任何搜索条件的值

  if(  we need to add a condition on city ) {
      $sth->bindValue(':city',$city);
  }
  if(  we need to add a condition on province ) {
      $sth->bindValue(':province',$province);
  }
  if(  we need to add a condition on name  ) {
      $sth->bindValue(':name',$name);
  }

执行

  $sth->execute();

另一种方法是在WHERE子句中使用带有表达式的静态SQL,使用" special"保留值代表"没有搜索"。

在这个例子中,我们使用零长度字符串表示"没有搜索条件" ...

  $sql = "SELECT ...
            FROM ... t
           WHERE ( :city1     = '' OR t.city     LIKE :city2     ) 
             AND ( :province1 = '' OR t.province LIKE :province2 )
             AND ( :name1     = '' OR t.name     LIKE :name2     )
           ORDER BY ...";

  $sth = $dbh->prepare($sql);

  $sth->bindValue(':city1'     , $city     ); 
  $sth->bindValue(':city2'     , $city     ); 
  $sth->bindValue(':province1' , $province ); 
  $sth->bindValue(':province2' , $province ); 
  $sth->bindValue(':name1'     , $name     ); 
  $sth->bindValue(':name2'     , $name     ); 

  $sth->execute();

答案 1 :(得分:0)

这可以在mysql或php中完成 - 但是imho的php解决方案看起来更干净。为此,您只需在运行时构建查询。

$name = ...
$city = ...
$province = ...

$fields = [
    'name' => $name,
    'city' => $city,
    'province' => $province
];
$where = [];
$values = [];

foreach ($fields as $field => $value) {
    if ($value) {
        $where[] = "$field = :$field";
        $values[$field] = $value;
    }
}

$sql = 'SELECT * FROM table';
if (count($where) > 0) {
    $sql .= ' WHERE ' . join(' AND ', $where);
}

// using pdo
$query = $pdo->prepare($sql);
$query->execute($values);
// ...

答案 2 :(得分:0)

您可以执行以下操作,将过滤器存储在数组中并检查每个过滤器是否存在。如果过滤器具有值,请使用where语句数组将其动态添加到where子句。

$filters = ['name', 'city', 'province'];
$where   = [];

foreach($filters as $filter) {
  if(!empty($_POST[$filter])) {
    $param_name          = ":{$filter}";
    $where[]             = "{$filter} = {$param_name}";
    $params[$param_name] = $_POST[$filter];
  }
}

$where_str = !empty($where) ? 'WHERE ' . join(' AND ', $where) : '';

$sql = "SELECT * FROM table {$where_str}";

$db = new PDO(<connection_str>);

$stmt = $db->prepare($sql);

$results = $stmt->execute($params);