i have a search function to search by different criteria from a db table.
here is the table' field with some data
id first_name last_name province_id
1 ali alii 2,12
2 ahmad ahmadi 22,1,4
a person can be in different province, and its saved in table separating by "," in province field, i know it is not normalized.
i use followed function for search
$WHERE_ARR = array();
if(trim($first_name)!=""){
$WHERE_ARR['first_name'] = " p.first_name like '%".$first_name."%' ";
}
if(trim($last_name)!=""){
$WHERE_ARR['last_name'] = " p.last_name like '%".$last_name."%' ";
}
if(trim($province)!=""){
$WHERE_ARR['province'] = " p.province_id = ".$province." ";
}
$WHERE_STR = implode(' AND ', $WHERE_ARR);
$WHERE_STR = (trim($WHERE_STR)!="")?" AND " . $WHERE_STR:'';
$QUERY = "
SELECT p.*,pr.province
FROM ndi_participants p,ndi_provinces pr
WHERE pr.province_id = p.province_id
". $WHERE_STR . "
ORDER BY pr.province ASC
LIMIT ".$start.", " . $perpage . "
";
return $this->db->query($QUERY);
for sure it is not exact when i search by province field.
how can i search by province field when it is multivalued separating by ","
note: i am using codeigniter
thanks for your helping
Try FIND_IN_SET mysql function to search in provience_id
if(trim($province)!=""){
$WHERE_ARR['province'] = " p.province_id = FIND_IN_SET(".$province.",p.province_id)";
}
Related
I would like to start from an example: you received some list with needed fields. This list may vary and even if it is empty, select all fields. This list can include fields from several tables. Is there any way to generate SELECT query for doing this?
Probably there is a way, but it will look like parsing received list, adding appropriate table alias, and then adding modified list into select clause. Is it best way actually?
Update 1
The goal is only to get passed fields from several tables, not to
control result from any of them(its about first answer)
You could create a query that first selects dynamically fields, depending on your criteria.
for example lets assume you have two criteria passed to you. Then (after you have made sure your criteria1 and criteria2 are safe):
$mySelect = ''; //placeholder so that you can add select fields
$extraTables = ''; //placeholder to put the extra tables I may need
$criteria = " WHERE 1 "; //this will select everything
if ($criteria1>'') {
$mySelect .= ' , t3.field3 ';
$extraTables = " , aDifferentTable AS t3";
$criteria .= " AND t3.someKey = t1.someKey '";
$criteria .= " AND field_crit1 = '" . $criteria1 . "'";
}
//and an example of connecting dynamically to an other table
if ($criteria2>'') {
$mySelect .= ' , t2.field5 ';
$extraTables = " , anOtherTable AS t2";
$criteria .= " AND t2.someKey = t1.someKey '";
$criteria .= " AND t2.field_crit2 = '" . $criteria2 . "'";
}
//lets combine all together into one dynamically created query
$myquery = "SELECT t1.something " . $mySelect . " FROM myTable AS t1";
$myquery = $myqury . $extraTables . $criteria;
so I am building a search script and meed to pass on two variables, but first I want to make sure that the SQL QUery is correct so I am hard-coding the variable for now. So my variable is
$comma_separated = "'Alberta','Ontario'";
This is getting passed through to the query, which looks like this:
$sql = "SELECT * FROM persons WHERE 1=1";
if ($firstname)
$sql .= " AND firstname='" . mysqli_real_escape_string($mysqli,$firstname) . "'";
if ($surname)
$sql .= " AND surname='" . mysqli_real_escape_string($mysqli,$surname) . "'";
if ($province)
$sql .= " AND province='" . mysqli_real_escape_string($mysqli,$comma_separated) . "' WHERE province IN ($comma_separated)";
$sql .= " ORDER BY surname";
and then when the query runs, I get this message:
cannot run the query because: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE province IN ('Alberta','Ontario') ORDER BY surname LIMIT 0, 5' at line 1
But to me the query looks right, what am I missing here?
Thanks in advance.
You can't have WHERE in there twice. You also seem to be trying to filter on province values in two different ways. Based on the assumption that $province will always be an array of values (even if only a single value is given), you can try this:
$sql = "SELECT * FROM persons WHERE 1=1";
if (!empty($firstname)) {
$sql .= " AND firstname='" . mysqli_real_escape_string($mysqli,$firstname) . "'";
}
if (!empty($surname)) {
$sql .= " AND surname='" . mysqli_real_escape_string($mysqli,$surname) . "'";
}
if (!empty($province)) {
array_walk($province, function($value, $key_not_used) use ($mysqli) {
return mysqli_real_escape_string($mysqli, $value);
});
$sql .= " AND province IN ('" . implode(',', $province) . "')";
}
$sql .= " ORDER BY surname";
Your SQL contains two WHERE's.
SELECT * FROM persons WHERE 1=1
AND firstname='fn'
AND surname='sn'
AND province='p'
WHERE province IN ($comma_separated)
ORDER BY surname
Change the last bit to:
$sql .= " AND province='" . mysqli_real_escape_string($mysqli,$comma_separated) . "' AND province IN ($comma_separated)";
Which becomes:
AND province='p'
AND province IN ('Alberta','Ontario')
Change the last part to:
if ($province)
$sql .= " AND province IN (" . mysqli_real_escape_string($mysqli,$comma_separated) . ")";
I have one problem while retrieveing value from mysql using codeigniter.
I have one table name task and in that there is one field of assigneduserid.
Table - Task:
id | title | Title | assigneduserid
--------------------------------------------------------
1 | Workspace |PMS | 23,21
Table - User
id | title
-----------------
23 | Ashish
21 | Ritesh
In assigneduserid field there are two values in that field that is 23,21.
I want to display task title in both user login.
but it displays only to Ashish login.
how can i solve it??
Following is my model:-
function getTask($id, $is_master_admin) {
$this->db->select('task.*, workspace.title as workspacetitle, user.title as usertitle');
$this->db->join(WORKSPACE, WORKSPACE . '.id = ' . TASK . '.workspaceid', 'inner');
$this->db->join(USER, USER . '.id = ' . TASK . '.userid', 'inner');
$this->db->from(TASK);
$this->db->group_by('task.id');
if (!$is_master_admin) {
$this->db->where(USER . '.id', $id);
}
$this->db->where(TASK . '.tasktypeid', '1');
$query = $this->db->get();
if ($query->num_rows() > 0) {
return $query->result();
} else {
return false;
}
}
Can any one please help??
function getTask($id, $is_master_admin) {
$data= $this->db->group_by('task.id')->get('task')->result();//check what value your getting in data and then use foreach and select the user from the user table
foreach($data as $value):
$array= $this->db->where('id',$value->id)->get('user')->result();
endforeach;
}
Try, Haven't checked it,
$tsql = " SELECT task.*, workspace.title AS workspacetitle, GROUP_CONCAT(user.title ORDER BY id) AS usertitle ".
" INNER JOIN ". WORKSPACE ." ON ". WORKSPACE .".id = " . TASK . ".workspaceid ".
" INNER JOIN USER ON FIND_IN_SET(".USER . ".id, ". TASK .".assigneduserid ) > 0 ".
" FROM ". TASK ;
if (!$is_master_admin) {
$tsql .= " WHERE ". USER . ".id =". $id;
}
$tsql .= " WHERE ". TASK . ".tasktypeid =1 ";
$tsql .= " GROUP BY ". TASK .".id ";
$query = $this->db->query($tsql);
I'm having a little trouble with a search form I've been creating the functionality for. I basically want a form (on whatever page) to go to this page then list the relevant rows from my database. My problem is that the form has both a text field and a select field (for name and categories) and I've been unable to create the functionality for having these two values search the database together.
So heres what I want to happen: When you only type in the name and not the category, it will display from just the name, vise versa for the category and no name; then when both together it only displays rows with both of them in.
Heres what I have so far:
// 2. Create variables to store values
if(!$_GET['search-category'] == "") {
$searchName = $_GET['search-name'];
}
if(!$_GET['search-category'] == "select-your-category") {
$searchCat = $_GET['search-category'];
}
// 2. Create the query for the stored value. Matching it against the name, summary and sub type of my item.
$mainSearch = "SELECT attraction.*, type.type_name, sub_type.sub_type_name ";
$mainSearch .= "FROM attraction ";
$mainSearch .= "INNER JOIN sub_type ON attraction.sub_type = sub_type.sub_type_id ";
$mainSearch .= "INNER JOIN type ON attraction.type = type.type_id ";
$mainSearch .= "WHERE attraction.name LIKE '%" . $searchName . "%' AND (sub_type.sub_type_name LIKE '%" . $searchCat . "%' )";
$mainSearch .= "ORDER BY sub_type_name ASC";
// 2. run query
$result2 = $con->query($mainSearch);
if (!$result2) {
die('Query error: ' . mysqli_error($result2));
}
I'd refactor the code to something like -
foreach( $_GET['filters'] as $fname => $fval ) {
if( !$fval ) continue;
$where[] = "$fname LIKE '%{$fval}%'";
}
You need to include only those inputs that are non-empty in the query. Also you will need to address security issues like escaping inputs etc.
What you can do is that declare a variable called $search_condition and based on whether $searchName or $searchCat is null or not assign value to $search_condition
For e.g.
if (isset($searchName ) || !is_empty($searchName ))
{
$search_condition = "WHERE attraction.name LIKE '%" . $searchName;
}
if (isset($searchCat ) || !is_empty($searchCat ))
{
$search_condition = "sub_type.sub_type_name LIKE '%" . $searchCat . "%'";
}
if ((isset($searchName ) || !is_empty($searchName )) && (isset($searchCat ) || !is_empty($searchCat )))
{
$search_condition = "WHERE attraction.name LIKE '%" . $searchName . "%' AND (sub_type.sub_type_name LIKE '%" . $searchCat . "%' )";
}
Hope this might help you
Thanks
This is a comment, but I want to take advantage of formatting options...
You know, you can rewrite that this way...
// 2. Create the query for the stored value. Matching it against the name, summary and sub type of my item.
$mainSearch = "
SELECT a.*
, t.type_name
, s.sub_type_name
FROM attraction a
JOIN sub_type s
ON a.sub_type = s.sub_type_id
JOIN type t
ON a.type = t.type_id
WHERE a.name LIKE '%$searchName%'
AND s.sub_type_name LIKE '%$searchCat%'
ORDER
BY s.sub_type_name ASC;
";
You can just check that the relevant values aren't empty:
// 2. Create the query for the stored value.
// Matching it against the name, summary and sub type of my item.
$mainSearch = "SELECT attraction.*, type.type_name, sub_type.sub_type_name ";
$mainSearch .= "FROM attraction ";
$mainSearch .= "INNER JOIN sub_type ON attraction.sub_type = sub_type.sub_type_id ";
$mainSearch .= "INNER JOIN type ON attraction.type = type.type_id ";
$mainSearch .= "WHERE ";
if ($searchName) {
$mainSearch .= "attraction.name LIKE '%" . $searchName . "%'";
if ($searchCat) {
$mainSearch .= " AND ";
}
}
if ($searchCat) {
$mainSearch .= "sub_type.sub_type_name LIKE '%" . $searchCat . "%'"
}
$mainSearch .= "ORDER BY sub_type_name ASC";
// Double check that at least one of the search criteria is filled:
if (!$searchName && !$searchCat) {
die("Must supply either name search or category search");
}
I am trying to make dynamic product filtering for opencart in which user could add filters, assign them to categories and assign filter values for products.
Currently I Have these mysql tables:
Filters - ID NAME
Filters_categories - ID FILTER_ID CATEGORY_ID
Filters_values - ID FILTER_ID VALUE
Filters_products - ID FILTER_ID VALUE_ID PRODUCT_ID
The problem is with this structure that i can't get products when more than one filter is activated because i get MySQL query which looks something like this:
SELECT product_id FROM Filters_products WHERE ((name_id='1' OR name_id='2') AND filter_id='1') AND ((name_id='3' OR name_id='4') AND filter_id='2')
And it doesn't make any sense. I can't figure out how should i change my database structure to make dynamic filtering possible. How can I solve this situation?
Thank you.
SELECT product_id FROM Filters_products WHERE (screen_id='1' OR screen_id='2') and (connection_id='1')
Use this awesome extension,
http://www.opencart.com/index.php?route=extension/extension/info&extension_id=10098
Hope this helps.
in file /catalog/model/catalog/product.php find line nr. 91 and replace "if {}" block whit this code...
if (!empty($data['filter_category_id'])) {
if (!empty($data['filter_sub_category'])) {
$sql .= " AND cp.path_id = '" . (int)$data['filter_category_id'] . "'";
} else {
$sql .= " AND p2c.category_id = '" . (int)$data['filter_category_id'] . "'";
}
if (!empty($data['filter_filter'])) {
$implode = array();
$filters = explode(',', $data['filter_filter']);
foreach ($filters as $filter_id) {
$filterSQL = $this->db->query("SELECT * FROM " . DB_PREFIX . "filter WHERE filter_id = ". $filter_id);
$implode[$filterSQL->row['filter_group_id']][] = (int)$filter_id;
}
foreach($implode AS $implode2) {
$sql .= " AND (";
foreach($implode2 AS $filterID) {
$sql .= "(SELECT count(*) FROM product_filter WHERE product_filter.product_id=p.product_id AND product_filter.filter_id=$filterID) OR ";
}
$sql = substr($sql, 0, -4);
$sql .= ")";
}
}
}