我有一个有效的搜索查询,但不是我希望的方式。这里:
try{
/*
Create Search Query.
*/
//Include database config file.
include('config.php');
//Get values from Angular.
$valuesPost=$_POST;
$values=array();
foreach ($valuesPost as $rows) {
$decodedValues=json_decode($rows, TRUE);
$values[]=$decodedValues;
}
//Get table from post values.
$table=$values[0]["table"];
//Get limit from post values.
$limit=$values[0]["limit"];
//Get offset from post values.
$offset=$values[0]["offset"];
//Get orderBy from post values.
$orderBy=$values[0]["orderBy"];
//Unset Whole array
unset($values[0]);
//Create cats fields
$cats=array_keys($values[1]);
if(empty($cats)) {
$cats = null;
} else {
foreach($cats as &$val){
$val="cat_id = :".$val;
}
$cats=implode(" OR ", $cats);
}
//Create subCats fields
$subCats=array_keys($values[2]);
if(empty($values[2])) {
$subCats[0] = null;
} else {
foreach($subCats as &$val){
$val="sub_cat_id = :".$val;
}
$subCats=implode(" OR ", $subCats);
}
//Create colourCats fields
$colourCats=array_keys($values[3]);
if(empty($colourCats)) {
$colourCats[0] = null;
} else {
foreach($colourCats as &$val){
$val="colour_id = :".$val;
}
$colourCats=implode(" OR ", $colourCats);
}
$where = "";
//Create Where Statement
if(empty($cats[0]) && empty($subCats[0])){
$where = $colourCats;
}
if(empty($cats[0]) && empty($colourCats[0])){
$where = $subCats;
}
if(empty($subCats[0]) && empty($colourCats[0])){
$where = $cats;
}
if(empty($colourCats[0]) && !empty($cats[0]) && !empty($subCats[0])){
$where = $cats." AND ".$subCats;
}
if(empty($subCats[0]) && !empty($cats[0]) && !empty($colourCats[0])){
$where = $cats." AND ".$colourCats;
}
if(empty($cats[0]) && !empty($subCats[0]) && !empty($colourCats[0])){
$where = $subCats." AND ".$colourCats;
}
if(!empty($cats[0]) && !empty($subCats[0]) && !empty($colourCats[0])){
$where = $cats." AND ".$subCats." AND ".$colourCats;
}
//Search query.
$search="SELECT * FROM $table WHERE $where ORDER BY $orderBy LIMIT $limit OFFSET $offset";
/*
Database Connection.
*/
//Crate a database connection variable: $conn and error checking attributes.
$conn = new PDO($DB_SETTINGS, $DB_USER, $DB_PASS);
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
/*
PDO WORK.
*/
//SEARCH_LIKE_ALL QUERY!
//Prepare query.
$search_qry=$conn->prepare($search);
//For each array index create array $rows.
foreach ($values as $rows) {
//Bind each value to $value_fields from $rows array.
foreach ($rows as $key => &$value) {
switch(gettype($value)) {
case 'integer':
case 'double':
$search_qry->bindParam(':' . $key, $value, PDO::PARAM_INT);
break;
default:
$search_qry->bindParam(':' . $key, $value, PDO::PARAM_STR);
}
}
}
$search_qry->execute();
$rows = $search_qry->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($rows);
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
它构建查询很好。在我的angularjs脚本中,我构建了一个多维数组,其中index [0]包含诸如table,orderby和limits之类的数据。索引[1]包含一系列类别。索引[2]子类别数组和索引[3]颜色类别数组。我的问题是搜索查询带回了我不期望的数据。所以我要说我发送这种类型的数组:
values[0]={table: table, order_by: prod_code, limit: 10, offset 0}
values[1]={cat_id0: 1};
values[2]={sub_cat_id0: 1, sub_cat_id1: 3}
values[3]={colour_id0: 1, colour_id1: 2}
我只想要猫1中的产品与子猫2& 3和颜色id 1& 2.当我从数组中删除子cat id但仍处于搜索状态时,它正在改变顺序,我假设此产品稍后被颜色ID拾取。查询是错误的还是我搜索的方式。
从上面的数组:
$search="SELECT * FROM table WHERE cat_id=:cat_id0 AND sub_cat_id=:sub_cat_id0 OR sub_cat_id=:sub_cat_id1 AND colour_id=:colour_id0 OR colour_id=:colour_id1 ORDER BY prod_code LIMIT 10 OFFSET 0"
答案 0 :(得分:1)
我认为您遇到的最大问题是AND
和OR
之间的优先顺序。
SELECT a
, b
, c
, a OR b AND c
, (a OR b) AND c
FROM ( SELECT 1 AS a UNION SELECT 0 ) a
CROSS
JOIN ( SELECT 1 AS b UNION SELECT 0 ) b
CROSS
JOIN ( SELECT 1 AS c UNION SELECT 0 ) c
WHERE NOT (a.a = b.b AND a.a = c.c)
ORDER BY c, b, a
a b c a OR b AND c (a OR b) AND c
------ ------ ------ ------------ --------------
1 0 0 1 0
0 1 0 0 0
1 1 0 1 0
0 0 1 0 0
1 0 1 1 1
0 1 1 1 1
也就是说
foo = a OR foo = b AND bar = c
评估为:
( foo = a ) OR ( foo = b AND bar = c )
当你可能想要的是:
(foo = a OR foo = b ) AND ( bar = c )
我无法破译代码正在执行的操作。
例如,为什么在构建WHERE
子句时需要所有这些条件的排列?为什么所有这些检查?为什么不简单,比如:
$where = " 1=1";
if (!empty($cats[0]) {
$where .= " AND (" . $cats . ")";
}
if (!empty($subCats[0]) {
$where .= " AND (" . $subCats . ")";
}
if (!empty($colourCats[0]) {
$where .= " AND (" . $colourCats . ")";
}
此外,测试平等的所有OR
条件
foo = a OR foo = b OR foo = c OR foo = d
使用IN
foo IN (a,b,c,d)
//Create cats fields
$cats=array_keys($values[1]);
if(empty($cats)) {
$cats = null;
} else {
$cats=" cat_id IN (". implode(",",$cats) . ");
}