MySql - autocomplete - sql

I am creating an Ajax autocomplete application and would like know if there is an SQL query I can use for this purpose - e.g if someone types "p" I would like to retrieve all words beginning with "p", if they add "e" retrieve all words starting with "pe" - and continue like that.
Someone suggested the query below but I don't think it's what I'm looking for:
$query = "SELECT* FROM nametable WHERE names LIKE '$partialstring' ";

$query = "SELECT* FROM nametable WHERE names LIKE '$partialstring%' ";
I've added % only on the right side since you would like to have only the words that are beginning with the input letters.
However, please don't use this query until you've filtered it against SQL injections.

This should work:
$query = "SELECT * FROM nametable WHERE names LIKE '$partialstring%'"
The %is the wildcard character in SQL.
Edit: And yes, please sanitize that input.

Apart from regular special chars, you have to escape those with a special meaning in LIKE clauses.
I haven't fully tested the code but it should be something like this, assuming you are using PHP and the good old mysql extension (you don't mention):
$escape = '|';
$like = strtr(
mysql_real_escape_string($partialstring),
array(
'%' => $escape . '%',
'_' => $escape . '_',
$escape => $escape . $escape,
)
);
$query = "SELECT names FROM nametable WHERE names LIKE '$like%' ESCAPE '$escape' ORDER BY names LIMIT 10";
Also, don't forget to create an index on the names column.

Assuming you are sanitising that input, it should be something like:
$query = "SELECT* FROM nametable WHERE names LIKE '$partialstring%' ";

You can run a query like what Henning and others have written. And, yes, please sanitize the input to prevent injection attacks. I have also found this method to be rather slow when there are a lot of records. If you wish to match 'Bush' in the word 'GeorgeWBushSenior' ,the above said method wont work. In which case you have to use the query
select name from nametable where name like '%match%';
Try looking at the mysql full text query method. Its extremely handy in some cases.

Related

What is the proper syntax for an Ecto query using ilike and SQL concatenation?

I am attempting to make an Ecto query where I concatenate the first and last name of a given query result, then perform an ilike search using a query string. For example, I may want to search the database for all names that start with "Bob J". Currently, my code looks like this:
pending_result_custom_search = from result in pending_result_query,
where: ilike(fragment("CONCAT(?, '',?)", result.first_name, result.last_name), ^query)
(pending_result_query is a previous query that I am composing on top of)
This approach does not work and I continue to get an empty query set. If I perform the query doing something like this
query = "Bob"
pending_result_custom_search = from result in pending_result_query,
where: ilike(fragment("CONCAT(?, '',?)", "%Bob%", ""), ^query)
I get the correct functionality.
What is the proper syntax to get the first approach working properly?
I think in your case I would use only fragment, e.g.
query = "%" <> "Bob" <> "%"
pending_result_custom_search = from result in pending_result_query,
where: fragment("first_name || last_name ILIKE = ?", ^query)
That way you can shift the focus to PostGres and use its functions instead of worrying too much about the Ecto abstractions of them. In the above example, I used || to concatenate column values, but you could use PostGres' CONCAT() if you desired:
pending_result_custom_search = from result in pending_result_query,
where: fragment("CONCAT(first_name, last_name) ILIKE = ?", ^query)
Note that both examples here did not include a space between first_name and last_name. Also, I added the % characters to the search query before binding it.

LINQ inserts 'ESCAPE N'~' in query

When I examine the SQL query the Linq spits out, I noticed that it places a ESCAPE N'~' when doing a LIKE command. How do I get rid of this? It seems like the query takes twice as long with the ESCAPE is in the SQL.
Here is the LINQ
var SearchPhrase = "xyz";
var result = (from i in db.myTable
where i.col1.contains(SearchPhrase)
select i).toList();
When I look at the actual SQL it looks something like this:
SELECT
[Extent1].Col1
FROM myTable As [Extent1]
WHERE [Extent1].Col1 LIKE #p__linq__3 ESCAPE N'~'
Apparently,
var SearchPhrase = "xyz";
var result = (from I in db.myTabl
where i.col1.contains(SearchPhrase)
select I).toList();
will add ESCAPE N'~' in the underlying query.
However using a constant filter like the following, doesn't produce escape characters in the underlying query
var result = (from I in db.myTabl
where i.col1.contains("xyz")
select I).toList();
Which means, variable filters are escaped, while constants are not.
So, in this case, we need a variable to be used as a constant filter.
Using the following, shouldn't add any escape characters:
var SearchPhrase = "xyz";
var result = (from I in db.myTabl
where SqlMethods.Like(i.col1, string.Format("%{0}%", SearchPhrase))
select I).toList();
but this works only with LINQ to SQL.
The other alternative is to embed the variable value as a constant, which is done using the following as explained in the SO article
Linq to Sql use '`' as it's default escape character when doing like comparisons. It will only cause a problem if your string actually contains ~ characters.
Use SqlMethods.Like to override this.
If you use LINQ 2 Entities, use SqlQuery to remove the "~" character.
Just append the value to compare like an ordinary sql query.
For example:
var resultList = context.TableName.SqlQuery(
"SELECT * FROM TableName WHERE field LIKE '%" + fieldValue+ "%' ").ToList();

Using Wildcards in SQL Where statement

I've got the following code:
SELECT ItemName
FROM skuDetails
WHERE skuDetails.SkuNumber = '" & search & "'
OR
skuDetails.ItemName = '%' + #search + '%'"
Basically I've got a database of items and each item has a "SKU number" which is a unique number for each item. In VB.NET I have a form where you type in either the SKU number or the name of the item into a text box and then press enter to search the database for that number or a similar name to the one you searched.
The "search" variable in the code above is the text in the textbox which the user searches.
The first WHERE statement works but the second after the OR doesn't. I expect it's something to do with how I've used the wildcard. Is there anything wrong with that statement?
Thanks in advance!
You should use LIKE rather than equals operator in order to use pattern matching:
OR skuDetails.ItemName LIKE '%' ...
MSDN: Pattern Matching in Search Conditions
The LIKE keyword searches for character string, date, or time values
that match a specified pattern. For more information, see Data Types
(Transact-SQL). The LIKE keyword uses a regular expression to contain
the pattern that the values are matched against. The pattern contains
the character string to search for, which can contain any combination
of four wildcards
To use a wildcard, you have to say LIKE '%' + #search + '%'
Be careful though, you are opening yourself up to SQL Injection attacks with this kind of code.

Search for “whole word match” with SQL Server LIKE pattern

Does anyone have a LIKE pattern that matches whole words only?
It needs to account for spaces, punctuation, and start/end of string as word boundaries.
I am not using SQL Full Text Search as that is not available. I don't think it would be necessary for a simple keyword search when LIKE should be able to do the trick. However if anyone has tested performance of Full Text Search against LIKE patterns, I would be interested to hear.
Edit:
I got it to this stage, but it does not match start/end of string as a word boundary.
where DealTitle like '%[^a-zA-Z]pit[^a-zA-Z]%'
I want this to match "pit" but not "spit" in a sentence or as a single word.
E.g. DealTitle might contain "a pit of despair" or "pit your wits" or "a pit" or "a pit." or "pit!" or just "pit".
Full text indexes is the answer.
The poor cousin alternative is
'.' + column + '.' LIKE '%[^a-z]pit[^a-z]%'
FYI unless you are using _CS collation, there is no need for a-zA-Z
you can just use below condition for whitespace delimiters:
(' '+YOUR_FIELD_NAME+' ') like '% doc %'
it works faster and better than other solutions. so in your case it works fine with "a pit of despair" or "pit your wits" or "a pit" or "a pit." or just "pit", but not works for "pit!".
I think the recommended patterns exclude words with do not have any character at the beginning or at the end. I would use the following additional criteria.
where DealTitle like '%[^a-z]pit[^a-z]%' OR
DealTitle like 'pit[^a-z]%' OR
DealTitle like '%[^a-z]pit'
I hope it helps you guys!
Surround your string with spaces and create a test column like this:
SELECT t.DealTitle
FROM yourtable t
CROSS APPLY (SELECT testDeal = ' ' + ISNULL(t.DealTitle,'') + ' ') fx1
WHERE fx1.testDeal LIKE '%[^a-z]pit[^a-z]%'
If you can use regexp operator in your SQL query..
For finding any combination of spaces, punctuation and start/end of string as word boundaries:
where DealTitle regexp '(^|[[:punct:]]|[[:space:]])pit([[:space:]]|[[:punct:]]|$)'
Another simple alternative:
WHERE DealTitle like '%[^a-z]pit[^a-z]%' OR
DealTitle like '[^a-z]pit[^a-z]%' OR
DealTitle like '%[^a-z]pit[^a-z]'
This is a good topic and I want to complement this to someone how needs to find some word in some string passing this as element of a query.
SELECT
ST.WORD, ND.TEXT_STRING
FROM
[ST_TABLE] ST
LEFT JOIN
[ND_TABLE] ND ON ND.TEXT_STRING LIKE '%[^a-z]' + ST.WORD + '[^a-z]%'
WHERE
ST.WORD = 'STACK_OVERFLOW' -- OPTIONAL
With this you can list all the incidences of the ST.WORD in the ND.TEXT_STRING and you can use the WHERE clausule to filter this using some word.
You could search for the entire string in SQL:
select * from YourTable where col1 like '%TheWord%'
Then you could filter the returned rows client site, adding the extra condition that it must be a whole word. For example, if it matches the regex:
\bTheWord\b
Another option is to use a CLR function, available in SQL Server 2005 and higher. That would allow you to search for the regex server-side. This MSDN artcile has the details of how to set up a dbo.RegexMatch function.
Try using charindex to find the match:
Select *
from table
where charindex( 'Whole word to be searched', columnname) > 0

MySQL query problem with 'like' and confusion

I need to use a string query to make a DB search for a C# program that interacts with MySQL server. What I want to find is a name that is 'like' one of my other variables (nameVar)
I have the following query in a C# program
string q = "SELECT *
FROM TABLE
WHERE name is like %?nameVar%";
As soon as execute the query in my program I get a syntax error telling me that syntax near
'like' is incorrect. As soon as I remove the "%" sign, it works fine.
I am confused, is mandatory to remove the % sign while building a query string?
Your parameter is replacing the ?nameVar part, including quotes. If the param is "TEST", your query gets presented as
string q = "SELECT *
FROM TABLE
WHERE name is like %'TEST'%";
As you can see, the % signs are out of place. either include them from the C# program into namevar, or change the query to
string q = "SELECT *
FROM TABLE
WHERE name is like '%' + ?nameVar + '%'";
you need to quote the query:
string q = "SELECT * from table where name is like '%?nameVar%'";
Strings in SQL need to be enclosed in single quotes:
string q = "SELECT *
FROM TABLE
WHERE name LIKE '%?nameVar%' ";
Also, there's no IS operator when using LIKE.
I think the correct syntax is:
SELECT * FROM table WHERE fields LIKE '%phrase%'
I think you have to leave out 'is'.
MySQL Pattern Matching