How does % wildcard exactly work in sql when searching - mysql

I saw a select statement with something like this in the where part 'LIKE %Blabla%Another%', now I tried it myself and I don't clearly understand how it works. The thing I'm confused about is the % in the middle, I understand how '%Blabla Another%' works, but with the % as a replacement for the space, I got confused.

% means "any sequence of characters, including an empty one". So LIKE '%Blabla%Another%' will match, for example 'XYZBlablaABCAnotherPQR', 'BlablaAnother' and ' Blabla Another '

% means any (including none) chars.
If you have a string 'abcdef' it would match e.g 'a%f' since the string start and ends with a and f.
'%b%e%'would also match as it means any string with b and even, in that order, but not necessarily next to each other

With LIKE you can use the following two wildcard characters in the pattern:
% matches any number of characters, even zero characters.
_ matches exactly one character.
© dev.mysql.com

In SQL, wildcard characters are used with the SQL LIKE operator.
there are the wild cards in sql %,_,[charlist],[^charlist].
the % wild cards is a substitute for zero or more characters.
for example
SELECT * FROM Customers
WHERE City LIKE '%es%';
this will selects all customers with a City containing the pattern "es".
so here you can see that the % wild card act as null or space character.

Here is a listing of the wildcards that you can use and below some examples.
%: A substitute for zero or more characters
_: A substitute for a single character
[charlist]: Sets and ranges of characters to match
[!charlist]: Matches only a character NOT specified within the brackets
The following SQL statement selects all customers with a City containing the pattern "es"
SELECT * FROM Customers WHERE City LIKE '%es%'
The following SQL statement selects all customers with a City starting with any character, followed by "erlin":
SELECT * FROM Customers WHERE City LIKE '_erlin'
The following SQL statement selects all customers with a City starting with "b", "s", or "p":
SELECT * FROM Customers WHERE City LIKE '[bsp]%'
The following SQL statement selects all customers with a City NOT starting with "b", "s", or "p":
SELECT * FROM Customers WHERE City LIKE '[!bsp]%'
Source: http://www.w3schools.com/sql/sql_wildcards.asp

Related

Why isn't MySQL REGEXP filtering out these values?

So I'm trying to find what "special characters" have been used in my customer names. I'm going through updating this query to find them all one-by-one, but it's still showing all customers with a - despite me trying to exlude that in the query.
Here's the query I'm using:
SELECT * FROM customer WHERE name REGEXP "[^\da-zA-Z\ \.\&\-\(\)\,]+";
This customer (and many others with a dash) are still showing in the query results:
Test-able Software Ltd
What am I missing? Based on that regexp, shouldn't that one be excluded from the query results?
Testing it on https://regex101.com/r/AMOwaj/1 shows there is no match.
Edit - So I want to FIND any which have characters other than the ones in the regex character set. Not exclude any which do have these characters.
Your code checks if the string contains any character that does not belong to the character class, while you want to ensure that none does belong to it.
You can use ^ and $ to check the while string at once:
SELECT * FROM customer WHERE name REGEXP '^[^\da-zA-Z .&\-(),]+$';
This would probably be simpler expressed with NOT, and without negating the character class:
SELECT * FROM customer WHERE name NOT REGEXP '[\da-zA-Z .&\-(),]';
Note that you don't need to escape all the characters within the character class, except probably for -.
Use [0-9] or [[:digit:]] to match digits irrespective of MySQL version.
Use the hyphen where it can't make part of a range construction.
Fix the expression as
SELECT * FROM customer WHERE name REGEXP "[^0-9a-zA-Z .&(),-]+";
If the entire text should match this pattern, enclose with ^ / $:
SELECT * FROM customer WHERE name REGEXP "^[^0-9a-zA-Z .&(),-]+$";
- implies a range except if it is first. (Well, after the "not" (^).)
So use
"[^-0-9a-zA-Z .&(),]"
I removed the + at the end because you don't really care how many; this way it will stop after finding one.

How to match any letter in SQL?

I want to return rows where certain fields follow a particular pattern such as whether a particular character in a string is a letter or number. To test it out, I want to return fields where the first letter is any letter. I used this code.
SELECT * FROM sales WHERE `customerfirstname` like '[a-z]%';
It returns nothing. So I would think that the criteria is the first character is a letter and then any following characters do not matter.
The following code works, but limits rows where the first character is an a.
SELECT * FROM sales WHERE `customerfirstname` like 'a%';
Am I not understanding pattern matching? Isn't it [a-z] or [A-Z] or [0-9] for any letter or number?
Also if I wanted to run this test on the second character in a string, wouldn't I use
SELECT * FROM `sales` WHERE `customerfirstname` like '_[a-z]%'
This is for SQL and MySQL. I am doing this in phpmyadmin.
You want to use regular expressions:
SELECT s.*
FROM sales s
WHERE s.customerfirstname REGEXP '^[a-zA-Z]';
This can be achieved with a regular expression.
SELECT * FROM sales WHERE REGEXP_LIKE(customerfirstname, '^[[:alpha:]]');
^ denotes the start of the string, while the [:alpha] character class matches any alphabetic character.
Just in case, here are a few others character classes that you may find useful :
alnum : dlphanumeric characters
digit: digit characters
lower : lowercase alphabetic characters
upper: uppercase alphabetic characters
See the mysql regexp docs for many more...

Regular expressions in Mysql/phpmyadmin

I have a question on a regular expression wanting to use MySQL / phpMyAdmin. Is the next:
^ [^ 0-9] $
As it is to not return any tuple in the table containing numbers, but the problem is that returns a tuple with contains numbers. The full statement is:
SELECT * FROM person WHERE name REGEXP "^ [^ 0-9] $";
So I do not know what is the problem. Because I have two tuples that have real names and a "false" tuple it is pure numbers and returns that tuple sentence with numbers.
Note: the "name" column in the "person" table is varchar.
It looks like you are trying to return columns that don't have numbers, is that correct?
If so I think
SELECT * FROM person WHERE name not REGEXP '[0-9]'
would be the simplest approach.
Your regex currently looks for a column that has a leading whitespace, a non-number or whitespace, and then a white space to end.
Demo: http://sqlfiddle.com/#!9/6b047/2
SELECT * FROM person WHERE name REGEXP '^[^0-9]+$'
You were close.See fiddle.

MySQL regex matching rows containing two or more spaces in a row

I am trying to write a MySQL statement which finds and returns the book registrations that contain 2 or more spaces in a row.
The statement below is wrong.
SELECT * FROM book WHERE titles REGEXP '[:space]{2,}';
Since the 2 spaces already meet your condition, you really do not need to check if there are more than 2. Moreover, if you need to match a regular ASCII space (decimal code 32), you do not need a REGEXP operator, you can safely use
SELECT * FROM book WHERE titles LIKE '% %';
LIKE is preferred in all cases where you can use it instead of REGEXP (see MySQL | REGEXP VS Like)
When you need to match numerous whitespace symbols, you can use WHERE titles REGEXP '[[:space:]]{2}' (it will match [ \t\r\n\v\f]), and if you only plan to match tabs and spaces, use WHERE titles REGEXP '[[:blank:]]{2}'. For more details, see POSIX Bracket Expressions.
Note that [:class_name:] should only be used inside a character class (i.e. inside another pair of [...], otherwise, they are not recognized.
Your POSIX class must be,
SELECT * FROM book WHERE titles REGEXP '[[:space:]]{2,}';
No need for ,
SELECT * FROM book WHERE titles REGEXP '[[:space:]]{2}';
You may also use [[:blank:]]
SELECT * FROM book WHERE titles REGEXP '[[:blank:]]{2}';
If you mean just the space character: REGEXP ' '. Or you could use LIKE "% %", which would be faster. (Note: there are 2 blanks in those.)
Otherwise, see http://dev.mysql.com/doc/refman/5.6/en/regexp.html for blank and space.

MySQL query - select postcode matches

I need to make a selection based on the first 2 characters of a field, so for example
SELECT * from table WHERE postcode LIKE 'rh%'
But this would select any record that contains those 2 characters at any point in the "postcode" field right? I am in need of a query that just selects the first 2 characters. Any pointerS?
Thanks
Your query is correct. It searches for postcodes starting with "rh".
In contrast, if you wanted to search for postcodes containing the string "rh" anywhere in the field, you would write:
SELECT * from table WHERE postcode LIKE '%rh%'
Edit:
To answer your comment, you can use either or both % and _ for relatively simple searches. As you have noticed already, % matches any number of characters whereas _ matches a single character.
So, in order to match postcodes starting with "RHx " (where x is any character) your query would be:
SELECT * from table WHERE postcode LIKE 'RH_ %'
(mind the space after _). For more complex search patterns, you need to read about regular expressions.
Further reading:
http://dev.mysql.com/doc/refman/5.1/en/pattern-matching.html
http://dev.mysql.com/doc/refman/5.1/en/regexp.html
LIKE '%rh%' will return all rows with 'rh' anywhere
LIKE 'rh%' will return all rows with 'rh' at the beginning
LIKE '%rh' will return all rows with 'rh' at the end.
If you want to get only first two characters 'rh', use MySQL SUBSTR() function
http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_substr
Dave, your way seems correct to me (and works on my test data). Using a leading % as well will match anywhere in the string which obviously isn't desirable when dealing with postcodes.