I have a string containing comma separated keywords. For Example:
$keywords = 'keyword1, keyword2, keyword3';
My Table schema, named tbl_address is like this ( simplified ) :
id INT(11) PRIMARY KEY, AUTO INCREMENT
address VARCHAR(250) NOT NULL
Assume I have to use MySQLi in PHP ( not PDO ).
Here is my current approach:
$result = array();
$keyword_tokens = explode(',', $keywords);
foreach($keyword_tokens as $keyword) {
$keyword = mysqli_real_escape_string(trim($keyword));
$sql = "SELECT * FROM tbl_address WHERE address LIKE'%$keyword%'";
// query and collect the result to $result
// before inserting to $result, check if the id exists in $result.
// if yes, skip.
}
return $result;
This approach works, but inefficient in performance. If there are a lot of keywords, it will make a lot queries.
My question is, is there a better way to achieve the same goal ? i.e. what is the simplest way to return all records with the address containing the ANY of the keywords ?
A simple REGEXP might be what you're after. You'd have to check how efficient it is for yourself.
SELECT * FROM tbl_address WHERE field REGEXP 'keyword1|keyword2|keyword3';
SELECT * FROM user;
+---------+----------+
| user_id | username |
+---------+----------+
| 101 | Adam |
| 102 | Ben |
| 103 | Charlie |
| 104 | Dave |
+---------+----------+
SELECT *
FROM user
WHERE FIND_IN_SET(username,'adam,ben,dave') > 0;
+---------+----------+
| user_id | username |
+---------+----------+
| 101 | Adam |
| 102 | Ben |
| 104 | Dave |
+---------+----------+
You only need an 'OR', nothing else...
<?php
$result = array();
$keyword_tokens = explode(',', $keywords);
$keyword_tokens = array_map('mysqli_real_escape_string', $keyword_tokens);
$sql = "SELECT * FROM tbl_address WHERE address LIKE'%";
$sql .= implode("%' or address LIKE '%", $keyword_tokens) . "'";
// query and collect the result to $result
// before inserting to $result, check if the id exists in $result.
// if yes, skip.
return $result;
edit: Just to be sure you also trim the keywords
<?php
$result = array();
$keyword_tokens = explode(',', $keywords);
$keyword_tokens = array_map(
function($keyword) {
return mysqli_real_escape_string(trim($keyword));
},
$keyword_tokens
);
$sql = "SELECT * FROM tbl_address WHERE address LIKE'%";
$sql .= implode("%' OR address LIKE '%", $keyword_tokens) . "'";
// query and collect the result to $result
// before inserting to $result, check if the id exists in $result.
// if yes, skip.
return $result;
Also, you should also pass the db resource link to the mysqli_real_escape_string() function...
The best way is to use fulltext search.
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
if you don't want to use fulltext you can use OR in your WHERE condition
SELECT * FROM tbl_address WHERE address LIKE '%$keyword%' OR adress LIKE '%$keyword2%'
Try WHERE IN clause:
$keyword = (array)explode(',', $keywords);
for($i=0;$i=count($keyword);$i++){
$keyword[$i]=mysqli_real_escape_string(trim($keyword[$i]),'\'" ');
}
//This is what I suggest.
$query='SELECT * FROM tbl_address WHERE address IN ("'.implode('","',$keyword).'")';
Successfully tested on MySQL 5.1.
Make single query
$keywordary = explode(',', $keywords);
foreach($keywordary as $keyword) {
$keys = trim($keyword);
$other .=" or address like '%$keys%'";
}
$sql = "SELECT * FROM tbl_address WHERE address LIKE'%$keyword%' $other";
execute query;
return $result;
Best way is just create search string WHERE clause and append it to query and run it once.
$result = array();
$keyword_tokens = explode(',', $keywords);
$where = '';$i=0
foreach($keyword_tokens as $keyword) {
$where.= " address LIKE'%".mysqli_real_escape_string(trim($keyword))."%' OR ";
}
// trim last OR with substr_replace
substr_replace($where, "OR", -1, 1);
$sql = "SELECT * FROM tbl_address WHERE $where";
return $result;
Hi create a query with union and execute in the end of the loop
$result = array();
$keyword_tokens = explode(',', $keywords);
$sql = '';
foreach($keyword_tokens as $keyword) {
$keyword = mysqli_real_escape_string(trim($keyword));
if (!empty($sql)) $sql .= " UNION ";
$sql .= "SELECT * FROM tbl_address WHERE address LIKE'%$keyword%'";
// query and collect the result to $result
// before inserting to $result, check if the id exists in $result.
// if yes, skip.
}
Execute the query here.
Related
I want to find a value from a column which has multiple values like (23,24,25), Using php mysqli query.
Table:
+-----------------+
id | tag_ids |
+-----------------+
1 | 3,4,5 |
2 | 3,7,8,9 |
3 | 4,5,10 |
Curent query:
$value = '3';
$query = "SELECT tag_ids FROM table WHERE FIND_IN_SET($value, tag_ids)";
$result = mysqli_query($query);
$count = mysqli_num_rows($result);
echo count;
Result will be: YES/NO or 1/0, if the Given value is match any value with tag_ids.
I found the result my self and here is code:
function statusvalues() {
$query = "SELECT tag_ids FROM tblname WHERE tag_ids !=''";
$result = mysqli_query($query, DBCONN);
$idarray = array();
while($row = mysqli_fetch_array($result)) {
array_push($idarray, $row['tag_ids']);
}
return $idarray;
}
function status($ID) { //Passing tag id
$set_of_numbers = statusvalues();
$reset_numbers = implode(", ", $set_of_numbers);
$values = explode(", ", $reset_numbers);
if (in_array($ID, $values)){
return "disabled";
}
}
This question already has answers here:
how to select unique keywords from a comma separated tags
(3 answers)
Closed 5 months ago.
This is my table tracks:
+---+--------------------+
| id| tag|
+---+--------------------+
| 1 | dance,|
| 2 | dance,tecno,|
| 3 | dance,hihop,|
| 4 | rap,|
| 5 | country,|
| . | ...|
+---+--------------------+
I tried this ($value is my query):
$tags = $this->db->query(sprintf("SELECT `tag`, `id` FROM `tracks` WHERE `tag` LIKE '%s' GROUP BY `tag` DESC LIMIT %s, %s", '%'.$this->db->real_escape_string($value).'%', $this->db->real_escape_string($start), $per_page));
while($row = $tags->fetch_assoc()) {
$rows[] = $row;
}
$tags = explode(',', $row['tag']);
$rows = array_unique(array_map('strtolower', $tags));
foreach($rows as $row) {
if(stripos($row, $value) !== false) {
$tag_output .= '<div class="hashtag-inner">
'.$row.'
</div>';
}
}
From this Eg. the output expected was: dance, tecno, hiphop, rap, country with all unique tags instead I have multiple output for the tag dance.
What's wrong with my output?
You need to call explode() in the loop that processes each row. Your code is just exploding the last row.
$rows = array();
while ($row = $tags->fetch_assoc()) {
$tags = explode(',', $row['tag']);
$rows = array_merge($rows, $tags);
}
$rows = array_unique(array_map('strtolower', array_filter($rows)));
array_filter() is used to remove the empty strings that come from the , at the end of the tag lists.
However, the best long-term solution would be to normalize your database schema so you don't store comma-separated lists in the table. You should have a table where each tag is in a separate row.
I think you need something like this
$tags = $this->db->query(sprintf("SELECT `tag`, `id` FROM `tracks` WHERE `tag` LIKE '%s' GROUP BY `tag` DESC LIMIT %s, %s", '%'.$this->db->real_escape_string($value).'%', $this->db->real_escape_string($start), $per_page));
$str = '';
while($row = $tags->fetch_assoc()) {
// combine all tags from "tag" column
$str .= $row['tag'];
}
$tags = explode(',', $str);
$rows = array_unique(array_map('strtolower', $tags));
foreach($rows as $row) {
if(stripos($row, $value) !== false) {
$tag_output .= '<div class="hashtag-inner">
'.$row.'
</div>';
}
}
I've saved all my data to an array, and I want to get the 'name' of a supplied 'code'.
How to I get the array row of that code?
Also, is this the most efficient process?
id | code | name |
__________________________
1 | KNTY | Kentucky |
2 | PURD | Purdue |
3 | TEXS | Texas |
// Move data to array
$search = "SELECT * FROM table";
$query = mysqli_query($conn, $search);
while($row = mysqli_fetch_assoc($query)) {
$array[] = $row;
}
// Code I want a name for
$code = "KNTY";
// MYSTERY STEP I NEED HELP WITH
$name = $array[$id]['name'];
I edit with the hint of the comment of itachi. You can use the code as the key of the $array:
$search = "SELECT * FROM table";
$query = mysqli_query($conn, $search);
$array = array();
while($row = mysqli_fetch_assoc($query)) {
$array[$row['code']] = $row['name'];
}
// Code I want a name for
$code = "KNTY";
$name = $array[$code];
Yes you could do something like that, while inside the fetch loop, assign the code as key. This must be unique though:
$search = 'SELECT * FROM table_name';
$query = mysqli_query($conn, $search);
while($row = mysqli_fetch_assoc($query)) {
// assign `$row['code']` as key to this rowset
$array[$row['code']] = $row;
}
$code = 'KNTY';
if(isset($array[$code])) { // add some checking, you wouldn't want undefined index errors
$name = $array[$code]['name'];
echo $name;
} else {
echo 'Sorry not found';
}
i have the following code.
i already try'd some sulotions from the search option, but nothing helped.
all tables have a row called: user_id with data in it, but still the query gives false
The $user variable has the value 29 and in my tables look like this:
+---------+---------+-------+-----------+
+ id | user_id | jaar + kenmerk |
+---------+---------+-------+-----------+
+ 1 | 29 | 2015 + standaard |
+---------+---------+-------+-----------+
$query = "SELECT buitenklimaat.user_id, kasklimaat.user_id, watermangement.user_id, energie.user_id FROM buitenklimaat, kasklimaat, watermangement, energie WHERE user_id = ".$user." AND kenmerk = 'standaard' AND jaar = ".date("Y")."";
$result = mysqli_query($conn, $query);
if($result === false) {
echo 'Query failed';
die();
}
else {
// do something
}
If the field user_id exists in more than one table, you need to prefix the field with the table name in your where clause, too. Otherwise your database will not know in which table it should look for the user_id field. But even after you fixed this error the query will probably not return what you want it to. Have a look at some SQL tutorials that cover the join syntax.
$query = "SELECT buitenklimaat.user_id, kasklimaat.user_id, watermangement.user_id, energie.user_id FROM buitenklimaat, kasklimaat, watermangement, energie WHERE <TABLENAME MISSING>.user_id = ".$user." AND kenmerk = 'standaard' AND jaar = ".date("Y")."";
You may need to join all those tables together to get the user_id condition to work properly:
$query = "SELECT buitenklimaat.user_id, kasklimaat.user_id,
watermangement.user_id, energie.user_id FROM buitenklimaat, kasklimaat,
watermangement, energie
WHERE buitenklimaat.user_id = kasklimaat.user_id
AND buitenklimaat.user_id = watermangement.user_id
AND buitenklimaat.user_id = energie .user_id
AND buitenklimaat.user_id = ".$user." AND kenmerk = 'standaard'
AND jaar = ".date("Y")."";
i want to get the field names and the row values into a single string.
example:
id | fname | gender | email
1 | john | male | 1#1.com
2 | mary | female | 2#2.com
select * from table where id=1
$this->db->where('id', 1);
$query = $this->db->get('table');
$row = $query->row();
$string = $row->id . $row->fname . $row->gender . $row->email;
Desire outcome:
id:1, fname:john, gender:male, email:1#1.com
or
id, fname, gender, email, 1, john, male, 1#1.com
Any advise on how to construct the sql query dynamically, many thanks.
$query = $this->db->query("select whatever from wherever.");
$string = "";
foreach ($query->result_array() as $row)
{
foreach($row as $key=>$val){$string.="$key:$val,";}
}
The only problem with selected answer is that if the query returns no records then you will not get any field names either.
You may prefer to get the field names discretely with the following command
$query = $this->db->query("select * from users");
$field_array = $query->list_fields();
$data = "";
foreach($field_array as $field){
$data .= $field . ", "
}