I'm trying to select a mssql row however I want to ignore the characters in a certain column before a certain character.
This is the column format:
|5555-55555|
I want to ignore everything before the dash "-" and only see if my variable $search shows up after. Then that's the row I want. I would prefer if it was an exact match. Is this possible or do I have to create a new column with just the number after the dash?
$search = '55555'
$query .= "WHERE '$columnName' LIKE '%$search%'";
Will match any *-55555
$search = '55555';
$query .= "WHERE '$columnName' LIKE '%-$search'";
Related
I have a user table with column ID and names. All of the ID's data starts with KM followed by 5 characters of number for example KM00001 (7 characters total). I want to make a search query where if the ID is typed in, it will only search in the ID column and if not it will automatically search in the name column.
if(isset($_POST['find'])) {
$find = $_POST['find'];
$query2 = mysqli_query($condb,"SELECT * FROM students WHERE id LIKE '$find' ");
$query = mysqli_fetch_array($query2);
}
You can use a regular expression to check if the input matches your predetermined ID format, and pick which column to search based on whether that's true or false.
In PHP, the command preg_match is used to check against regular expressions, so your script would look something like this:
if(isset($_POST['find'])) {
$find = $_POST['find'];
if (preg_match('/^KM\d{5}$/i', $find)) {
$column = 'id';
}
else {
$column = 'name';
}
$query2 = mysqli_query($condb,"SELECT * FROM students WHERE $column LIKE '$find' ");
$query = mysqli_fetch_array($query2);
}
(In the regular expression /^KM\d{5}$/i, "KM" are literal characters, \d matches any digit, {5} specifies that we want five digits, bookending that between ^ (beginning of string) and $ (end of string) ensures it only matches if the whole input string is an ID, and the "i" flag at the end makes the search case-insensitive.)
I am using MyISAM engine with fulltext indexing for storing a list of strings.
These strings can be a single word, or a sentence.
If I want to know how many times string hello appears in my table, I do
SELECT COUNT(*) Total
FROM String s
WHERE
MATCH (s.name) AGAINST ('hello')
I would like to create a similar report, but for all strings. Result should be a list of TOP-N strings that are the most common in this table (top ones most probably are "the", "a", "to" etc.).
Exact match case is pretty obvious:
SELECT name as String, count(*) as Total
FROM String
GROUP
BY name
ORDER
BY total desc
LIMIT *some number*
But it counts only whole strings.
Is there any way to achieve my desired result?
Thanks.
I guess there is no easy way for this. I would create a "statistic table" for this purpose only. One column for words themselves, one column for the number of occurrences. (Primary key on the first column of course.)
For this with a PL/SQL block scanning all strings, and split them for words.
If the string is not found in the statistic table, you insert a new row.
If the string is found in the statistic table, you increase the value in the second column.
This can run for a pretty long time, but after the first run is ready, you only have to check the new strings on insert, perhaps with a trigger. (Assuming you want to use it not once but regularly.)
Hope this helps, I have no simpler answer.
i think if you use the LIKE command will works
select name, count(*) as total from String where name like '%hello%' group by name order by total
let me know
I didn't find any solution with SQL and my Full text index, but I managed to get my desired result by getting all of my strings from DB and processing them on the backend with php:
//get all strings from DB
$queryResult = $db->query("SELECT name as String FROM String");
//Combine all of them into array
while($row = $queryResult->fetch_array(MYSQLI_ASSOC)) {
$stringArray[] = $row['String'];
}
//"Glue" all these strings into one huge string
$text = implode(" ", $stringArray);
//Make everything lowercase
$textLowercase = strtolower($text);
//Find all words
$result = preg_split('/[^a-z]/', $textLowercase, -1, PREG_SPLIT_NO_EMPTY);
//Filter some unwanted words
$result = array_filter($result, function($x){
return !preg_match("/^(.|the|and|of|to|it|in|or|is|a|an|not|are)$/",$x);
});
//Count a number of occurrence of each word
$result = array_count_values($result);
//Sort
arsort($result);
//Select TOP-N strings, where N is $amount
$result = array_slice($result, 0, $amount);
My mysql select query is getting 0 rows because of the values that are being put into the like statement. The example query is below:
$byear = '1975';
$search = "%205679%"; #example value
$query = $db->query("Select * FROM MDPay WHERE dobyear='".$byear."' and concat('|', PatID, FormatPhone, coalesce(' ' + cellphone + ' ', ' ')) like '".$search."'");
// result would be (0 rows) because the $search value converts the %20
This is returning (0) rows because the $search variable ends up being '5679' because the %20 is getting converted to whitespace. How do I keep php from converting it to whitespace?
I've tried using url_encode(), but I'm not sure how to keep it from converting the search value.
UPDATE: I have tried escaping the query, and I think the issue is PHP is parsing the %20 before it even get's sent through, so the values being sent to the query is '5679%'. How do I keep PHP from converting the value before the value is entered into the query?
Try to escape the like function
$byear = '1975';
$search = "#%20#5679%"; #example value
$query = $db->query("Select * FROM MDPay WHERE dobyear='".$byear."' and concat('|', PatID, FormatPhone, coalesce(' ' + cellphone + ' ', ' ')) like '".$search."' escape '#'");
This question already has answers here:
Regular expression to match common SQL syntax?
(13 answers)
Closed 9 years ago.
I need to retrieve table parent-child relationship from "WHERE" clause like this:
select ... large list of fields with aliases ...
from ... list of joined tables ...
where ((`db_name`.`catalog`.`group` = `db_name`.`catalog_group`.`iden`)
and (`db_name`.`catalog`.`iden` = `db_name`.`catalog_sub`.`parent`))
Is there a some regex to get identifiers from each condition? Say in an array element[0] = table from the left side, element[1] is table from right. Ident's name may be any. So only sql operators like 'where' 'and' '=' may be keys.
Any help would be greatly appreciated.
CLARIFY
I dont want to get references from WHERE clause by WHERE clause. I just want references as such. So as could I see there may be regex to replace all sequences
`.`
to
.
and then match all backticked pairs by
` # ` = ` # `
Backticks around identifier always present in any may query by default. All string values surrounded by double quotes by default. I thought it's not a complex task for regex guru. Thanks in advance.
PS It's because myISAM engine does not support references I forced to restore in manually.
ENDED with:
public function initRef($q) {
$s = strtolower($q);
// remove all string values within double quotes
$s = preg_replace('|"(\w+)"|', '', $q);
// split by 'where' clause
$arr = explode('where', $s);
if (isset($arr[1])) {
// remove all spaces and parenthesis
$s = preg_replace('/\s|\(|\}/', '', $arr[1]);
// replace `.` with .
$s = preg_replace('/(`\.`)/', '.', $s);
// replace `=` with =
$s = preg_replace("/(`=`)/", "=", $s);
// match pairs within ticks
preg_match_all('/`.*?`/', $s, $matches);
// recreate arr
$arr = array();
foreach($matches[0] as &$match) {
$match = preg_replace('/`/', '', $match); // now remove all backticks
$match = str_replace($this->db . '.', '', $match); // remove db_name
$arr[] = explode('=', $match); // split by = sign
}
$this->pairs = $arr;
} else {
$this->pairs = 0;
}
}
Using a regular expression seems like it won't help you. What if there are subqueries? What if your query contains a string with the text "WHERE" in it? Hakre mentioned it in a comment above, but your best bet really is using something that can actually interpret your SQL so that you can find what really is a proper WHERE clause and what is not.
If you insist on doing this the "wrong" way instead of by using some context aware parser, you would have to find the WHERE clause, for instance like this:
$parts = explode('WHERE', $query);
Assuming there is only one WHERE clause in your query, $parts[1] will then contain everything from the WHERE onwards. After that you would have to detect all valid clauses like ORDER BY, GROUP BY, LIMIT, etc. that could follow, and break off your string there. Something like this:
$parts = preg_split("/(GROUP BY|ORDER BY|LIMIT)|/", $parts[1]);
$where = $parts[0];
You would have to check the documentation for your flavor of SQL and the types of queries (SELECT, INSERT, UPDATE, etc.) you want to support for a full list of keywords that you want to split on.
After that, it would probably help to remove all brackets because precedence is not relevant for your problem and they make it harder to parse.
$where = preg_replace("/[()]/", "", $where);
From that point onward, you'd have to split again to find all the separate conditions:
$conditions = preg_split("/(AND|OR|XOR)/", $where);
And lastly, you'd have to split on operators to get the right and left values:
foreach ($conditions as $c)
{
$idents = preg_split("/(<>|=|>|<|IS|IS NOT)/");
}
You would have to check that list of operators and add to it if needed. $idents now has all possible identifiers in it.
You may want to note that several of these steps (at the very least the last step) will also require trimming of the string to work properly.
Disclaimer: again, I think this is a very bad idea. This code only works if there is only one WHERE clause and even then it depends on a lot of assumptions. A complicated query will probably break this code. Please use a SQL parser/interpreter instead.
I'm using a simple query for my search:
SELECT * FROM table WHERE field LIKE '%term%'
if I have a field = "Company Name 123" and I search for Company 123 the result is null
how can I improve this? it only finds if the term is in sequence
Replace spaces with %
$newTerm = str_replace(' ', '%', $term);
$sql = "SELECT * FROM table WHERE field LIKE '%$term%'"
$r = mysql_qery($sql, $conn);
You need to put a % between Company and 123 in order for it to match. You might want to check out full text search functions.
try to replace spaces
$searchtext =str_replace(' ','%',$searchtext);
you could:
split your searchterm into words and build a query with a lot of ANDs (or ORs if you just want to find one of the parts) out of it (ugly, but i've seen this a lot of times)
replace ' '(space) with % (thats a wildcard) in your term (the way to go)