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";
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`";
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;
?>
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 have an SQL LIKE query running on mySQL which runs fine on my local development server however on the production server it only works on single letters; i.e. if I enter a word any longer than one letter it returns no results.
Any ideas why and how I might be able to fix it?
Thank you in advance.
/**
* Searches all current vehicle listings for matches to given search string.
* #param string - Search keyword(s). Warning: If search string is empty all current vehicles are returned.
* #return array - Resulting table rows containing vin, imageFile, description, kms, auctioneerName, city, time.
*/
public function searchVehicles($search) { //
// Build up initial SQL query. Sub query returns all current vehicles
$query = "SELECT * FROM (SELECT vehicles.auctionId, vin, imageFile, CONCAT_WS(' ', year, makeName, modelName) as description, kms, auctioneerName, city, time FROM vehicles, models, makes, auctions, auctioneers, locations WHERE time > NOW() AND vehicles.modelId = models.modelId AND models.makeId = makes.makeId AND vehicles.auctionId = auctions.auctionId AND auctions.auctioneerId = auctioneers.auctioneerId AND auctions.locationId = locations.locationId) AS results WHERE";
$keywords = explode(" ", $search); // Break search into keywords
// Loop through each keyword in the search to build up SQL query
$firstLoop = true; // Initial loop flag
foreach ($keywords as $keyword) {
if (!$firstLoop) { // Check if this is not the first loop
$query = $query . " AND"; // Then: Add extension statement to query
} else {$firstLoop = false;} // Otherwise: Set flag to false
// Add each keyword search to the query ensuring case insensitivity by converting to uppercase
$query = $query . " UPPER(description) LIKE UPPER('%" . $this->escape($keyword) . "%')";
}
// Add ordering SQL
$query = $query . " ORDER BY time";
// Run query and return results (if any)
return $this->query($query);
}
$query = $query . " UPPER(description) LIKE '%" . strtoupper($this->escape($keyword)) . "%'";
try using COLLATE
$query = $query . " description COLLATE utf8_general_ci like '" . $this->escape($keyword) . ")%'";
for case insensitive search
Upper should be inside.
$query = $query . " UPPER(description) LIKE CONCAT('%',UPPER(" . $this->escape($keyword) . "),'%')";