I have a table that contains information such as names, email-addresses, numbers etc.
Let's pretend that I have 30 contacts by the same name but they all live in different cities . How do I split the comma and replace it with and ....
Example
SELECT * WHERE name %$searchString% OR city %$searchString%...
Now if $searchString contains comma
SELECT * WHERE name %$searchString% OR city %$searchString%... AND SELECT * WHERE name %$searchString2% OR city %$searchString2%...
The $searchString2 contains information that's separated with comma.
Update
I want to search each row over and over again as many times as commas exist.
I'm sorry that I can't explain myself
This depends on whether you want to return rows where name or city match the search values exactly (=), or rows where any part of name or city match the search values (LIKE).
Regardless of which one you need, you can start out by converting your search string into an array of strings like this:
$strings = array_map('trim', explode(',', $searchString));
The array_map('trim'... ensures that you don't try to match any spaces before or after the commas in your comma-separated search string.
Here are examples for how to execute your query using prepared statements in PDO. First, full matches using IN:
$phs = rtrim(str_repeat('?,', count($strings)),',');
$stmt = $pdo->prepare("SELECT * FROM your_table WHERE name IN ($phs) OR city IN ($phs)");
// double the string values to us in both INs
$values = array_merge($strings, $strings);
$stmt->execute($values);
and partial matches using LIKE:
$sql = '';
foreach ($strings as $string) {
$sql .= ' name LIKE ? OR city LIKE ? OR';
$values[] = $string;
$values[] = $string;
}
$stmt = $pdo->prepare('SELECT * FROM your_table WHERE' . rtrim($sql, ' OR'));
$stmt->execute($values);
You need to use WHERE IN in SQL statement.
SELECT * WHERE name LIKE '%$searchString%' AND city IN ('city1', 'city2', 'city3'...)
Here is the good discussion on how to do it in PHP: Passing an array to a query using a WHERE clause
Something like this?
You will need to escape/clean the value of searchString.
<?php
// $searchString = "Cardiff,London,New York";
$SQL = 'SELECT * FROM table WHERE ';
$searchStrings = explode(',',$searchString);
$SQLArray = array();
foreach($searchStrings as $searchString) {
$SQLArray[] = "name LIKE '%$searchString%'";
$SQLArray[] = "city LIKE '%$searchString%'";
}
$SQL .= implode(' OR ',$SQLArray);
// print $SQL;
?>
Related
I have a DB wherein one table, the column has a list of words separated by the comma, which has to be compared and select accordingly. but in PHP so far I have written SQL code for one word in a column cell-like,
<?PHP
$sql2 = "SELECT * FROM table WHERE name = 'name'";
$result2 = $conn->query($sql2);
if ($result2->num_rows > 0) {
while($row2 = $result2->fetch_assoc()) {
?>
but here, I have a list of words in the name column separated by a column.
how do I write code to extract all those words into single and check each one of them with the user input text?
Hope I m clear, Any help is appreciated..
Use filter_input() for Input,
use explode() for Input,
use SQL IN or SQL REGEX with and/or for SQL Part.
$clean_userinput = filter_input(INPUT_GET, "userinput", FILTER_SANITIZE_STRING);
like $_GET["userinput"]
$array_userinput = explode(" ", $clean_userinput);
$in = "(";
for($i=0;$i <count($array_userinput); $i++) {
$in .= "'" . trim($array_userinput[$i]) . "'";
}
$in .= ")"
$sql2 = "SELECT * FROM table WHERE name IN ". $in;
That all magic simple. php.net is your best source.
I´m trying to put together the most elegant way of searching in two fields for multiple (number of words can vary) terms that needs to only provide results when all words are found (AND instead of OR).
The below gives me an SQL syntax error message:
$search = $_GET["search"];
$searcharray = explode('|', $search);
$query=("SELECT username,sender,message,subject,timestamp,threadid,msgtype
FROM Messages WHERE ('" . implode("'|'",$searcharray) . "') IN CONCAT
(message,subject) ORDER BY timestamp");
I could of course set up a foreach loop for each match on the first word that breaks with an instruction to not add the result if any of the other words are not found in the two fields, but that´s alot more for the PHP script to handle, I think.
Any suggestions?
IN has to be followed by a list of values in parentheses, or a SELECT subquery. You can't use it for pattern matching.
To search a column for a word, you need to use LIKE, with % around the word. And there's no shortcut for searching for multiple words, you have to search for each of them and combine them with AND.
$tests = array_map(function($word) {
return "CONCAT(message, subject) LIKE '%$word%'";
}, $searcharray);
$where = implode(' AND ', $tests);
$query = "SELECT username,sender,message,subject,timestamp,threadid,msgtype
FROM Messages WHERE $where ORDER BY timestamp";
As mentioned in the comments, the code is suseptable to SQL injection. That being said, and since I don't want to re-write all of the code ;-), here's one way to construct the where clause.
$search = $_GET["search"];
$searcharray = explode('|', $search);
$qstr = "SELECT
`username`,
`sender`,
`message`,
`subject`,
`timestamp`,
`threadid`,
`msgtype`
FROM `Messages`
WHERE ";
$w = array();
foreach($searcharray as $key => $val) {
$w[] = "CONCAT(`message`,`subject`) LIKE '%" . $val . "%'";
}
$w_str = implode(" AND ",$w);
$qstr .= $w_str . " ORDER BY `timestamp`";
My application allows searching of articles. So when a user enters the string "articlex" the query works & results are show but when multiple words are entered "articlex articley" the query shows no results.
Cuurently I'm using this query
$querySub = 'SELECT * FROM table WHERE (col1 LIKE "%'.$search_string.'%") OR (col2 LIKE "%'.$search_string.'%") OR (col3 LIKE "%'.$search_string.'%")';
Where $search_string only contains the input by user
How can I make the query applicable for multiple words as well?
Example for PDO
/* Assume $pdo is already prepared as PDO instance. */
// search query split by spaces
$user_input = 'foo bar baz';
// create string for PDO::prepare()
$sql = 'SELECT * FROM testTable WHERE ';
$wheres = $values = array();
foreach (array_filter(explode(' ', $user_input), 'strlen') as $keyword) {
$wheres[] = 'col1 LIKE ?';
$values[] = '%' . addcslashes($keyword, '%_\\') . '%'; // this is escape for LIKE search
}
$sql .= $wheres ? implode(' OR ', $wheres) : '1';
// bind values and execute
$stmt = $pdo->prepare($sql);
$stmt->execute($values);
Example for mysql_** functions (deprecated)
/* Assume $link is already prepared as MySQL resource. */
// search query split by spaces
$user_input = 'foo bar baz';
// create string for mysql_auery()
$sql = 'SELECT * FROM testTable WHERE ';
foreach (array_filter(explode(' ', $user_input), 'strlen') as $keyword) {
$wheres[] = 'col1 LIKE ' . mysql_real_escape_string(
'%' . addcslashes($keyword, '%_\\') . '%',
$link
);
}
$sql .= !empty($wheres) ? implode(' OR ', $wheres) : '1';
// execute
$result = mysql_query($sql, $link);
While using variables for like query, you could use
Select * from table where keyword LIKE '%{$to_be_searched}%'
You can use REGEXP for this perpose .....or if you want multiple word search then you need to explode search string by space and then search this string from table using LIKE
if you search "articlex articley" then it will search whole word in LIKE operator
use only one "%" at the end. like
$querySub = SELECT * FROM table WHERE (col1 LIKE '$search_string%'");
This will search for both "articlex" and "articley"
1: This will be return should record
select * from products where title like "%word1%" or
title LIKE "word2";
note: if you have so many word then use dynamic query generator which generate title like "%word3%" or title like"%word4%" or ........
2: This will be return must records
select * from products where title like "%word1%word2%word3%";
I am trying to run a query to determine if a column A is true. If its true, get the contents of a different column B (possible array separated by ",") and use those contents to query a different table. My problem is, column B may be one number or may be 10 numbers all separated by "," and I need to query the second table for a column for each of the numbers of the previous query. If someone can help that would be great.
edit: I tried to use the array explode function but can't figure out how to query the next table to include those values.
I picture it being something like
query = select * from table where location = arrayValue[1] or location = arrayValue[2]
Adaptation of Telmo Marques here but improved :
<?php
//Let's say $bcolumn is a string with the values of B column, separated by colons
$bcolumnArray = explode(",", $bcolumn);
array_walk($bcolumnArray, 'htmlentities');
//Build SQL query
$SQL = 'SELECT * FROM table';
if(count($bcolumnArray)){
$SQL.= ' WHERE IN ("'.implode('", "', $vbcolumnArray).'")';
}
//Query your second table here
$Qry = mysql_query($sql);
// Results here :
while($Res = mysql_fetch_assoc($Qry)){
print_r($Res);
}
?>
I would suggest PDO also... take a look : PDO.
Use PHP's explode() function to transform your string into an array.
<?php
//Let's say $bcolumn is a string with the values of B column, separated by colons
$bcolumnArray = explode(",", $bcolumn);
//Build SQL query
$sql = "SELECT * FROM table WHERE ";
for($i=0; $i < count($bcolumnArray); $i++)
{
$sql .= "location = " . $value;
if($i != count($bcolumnArray)-1)
{
$sql .= " or ";
}
}
//Query your second table here
mysql_query($sql);
?>
Documentation: http://php.net/manual/en/function.explode.php
I am trying to query:
$title2 = (isset($row_DetailRS1['r_bus_name']) ? $row_DetailRS1['r_bus_name'] : "");
$query_test = "SELECT *
FROM table
WHERE r_email = '$email2'
AND r_city != '$location2'
AND r_bus_name LIKE '%$title2%'
ORDER BY r_bus_name";
The r_bus_name LIKE '%$title2' is defined from above and is grabbing the TITLE of the EVENT from the POST. The title is usually two to three words...
How do I query r_bus_name LIKE (any of the words in the event title $title2)?
Because right now it is taking the whole value of $title2.. I need to split them up or explode them in words, so if the title is something like "Test title here" then "Tester title here" would match?
If you want to search on EACH of the words in the title, you would need to construct a query using OR operations to apply them to the same query.
It might look something like this:
// break apart the title using spaces
$title2 = (isset($row_DetailRS1['r_bus_name']) ? $row_DetailRS1['r_bus_name'] : "");
$title_keywords = explode(" ", $title2);
// construct conditions (Note the ampersand causes pass-by-reference)
foreach($title_keywords as &$keyword) {
$keyword = "r_bus_name LIKE '%".mysql_real_escape_string($keyword)."%'";
}
$keyword_search = "(" . implode(" OR ", $title_keywords) . ")";
$query_test = "SELECT *
FROM table
WHERE r_email = '".mysql_real_escape_string($email2)."'
AND r_city != '".mysql_real_escape_string($location2)."'
AND ".$keyword_search."
ORDER BY r_bus_name";
// ...
Assuming the table is MyISAM, you could use the native Full Text Search (FTS) functionality:
$query = sprintf("SELECT t.*
FROM YOUR_TABLE t
WHERE t.r_email = '%s'
AND t.r_city != '%s'
AND MATCH(t.r_bus_name) AGAINST('%s')
ORDER BY t.r_bus_name",
mysql_real_escape_string($email2),
mysql_real_escape_string($location2),
mysql_real_escape_string($title2) );
$result = mysql_query($query);
Sadly, MySQL doesn't support FTS on the InnoDB engine.
Addendum
I recommend using sprintf if you aren't using PDO/etc for prepared statements, to protect against SQL injection attacks.
Split title2 on spaces and do multiple likes:
$titleArray = split(" ", $title2);
$query_test = "SELECT *
FROM table
WHERE r_email = '$email2'
AND r_city != '$location2'
AND ("
foreach ($title as titleArray)
$query_test .= "OR r_bus_name LIKE '%$title%'"
$query_test .= "ORDER BY r_bus_name";