SQL : Confused with WildCard operators - sql

what is difference between these two sql statements
1- select * from tblperson where name not like '[^AKG]%';
2- select * from tblperson where name like '[AKG]%';
showing same results: letter starting from a,k,g

like '[^AKG]% -- This gets you rows where the first character of name is not A,K or G. ^ matches any single character not in the specified set or a specified range of characters. There is one more negation not. So when you say name not like '[^AKG]%' you get rows where the first character of name is A,K or G.
name like '[AKG]% -- you get rows where the first character of name is A,K or G.
The wildcard character [] matches any character in a specified range or a set of characters. In your case it is a set of characters.
So both the conditions are equivalent.

You are using a double 'NOT'. The carrot '^' in your first character match is shorthand for 'not', so you are evaluating 'not like [not' AKG]% IE not like '[^AKG]%'.

1)In the first query you are using 'Not' and '^' basically it is Not twice so it cancels outs
therefore your query is 'Not Like [^AKG]' ==> 'Like [AKG]'

^ a.k.a caret or up arrow.
The purpose of this symbol is to provide a match for any characters not listed within the brackets [] , meaning that normally it wouldn't provide a result for anything that starts with AKG, but since you added the word NOT to the query , you are basically cancelling the operator, just as if you were doing in math :
(- 1) * (- 1)

Related

Find phone numbers with unexpected characters using SQL in Oracle?

I need to find rows where the phone number field contains unexpected characters.
Most of the values in this field look like:
123456-7890
This is expected. However, we are also seeing character values in this field such as * and #.
I want to find all rows where these unexpected character values exist.
Expected:
Numbers are expected
Hyphen with numbers is expected (hyphen alone is not)
NULL is expected
Empty is expected
Tried this:
WHERE phone_num is not like ' %[0-9,-,' ' ]%
Still getting rows where phone has numbers.
from https://regexr.com/3c53v address you can edit regex to match your needs.
I am going to use example regex for this purpose
select * from Table1
Where NOT REGEXP_LIKE(PhoneNumberColumn, '^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*$')
You can use translate()
...
WHERE translate(Phone_Number,'a1234567890-', 'a') is NOT NULL
This will strip out all valid characters leaving behind the invalid ones. If all the characters are valid, the result would be NULL. This does not validate the format, for that you'd need to use REGEXP_LIKE or something similar.
You can use regexp_like().
...
WHERE regexp_like(phone_num, '[^ 0123456789-]|^-|-$')
[^ 0123456789-] matches any character that is not a space nor a digit nor a hyphen. ^- matches a hyphen at the beginning and -$ on the end of the string. The pipes are "ors" i.e. a|b matches if pattern a matches of if pattern b matches.
Oracle has REGEXP_LIKE for regex compares:
WHERE REGEXP_LIKE(phone_num,'[^0-9''\-]')
If you're unfamiliar with regular expressions, there are plenty of good sites to help you build them. I like this one

How to avoid selecting row in sql server which has special symbol

How to avoid selecting row which has special symbol like mentioned below .
We can use range of ASCII character as below. CHAR(n) returns character value of integer ASCII code n
SELECT *
FROM yourTable
WHERE ID NOT LIKE '%['+CHAR(32) +'-'+CHAR(126)+']%'
OR Name NOT LIKE '%['+CHAR(32) +'-'+CHAR(126)+']%';
Refer ASCII characters
You could use SQL Server's enhanced LIKE operator:
SELECT *
FROM yourTable
WHERE ID NOT LIKE '%[^A-Za-z0-9_-]%' AND Name NOT LIKE '%[^A-Za-z0-9_-]%';
This would select only rows where both ID and Name columns do not contain any special characters. Special characters here are defined as anything other alphanumeric, underscore, and hyphen.

What is this Oracle regexp matching in this production code?

Here's the code that is in production:
dynamic_sql := q'[ with cte as
select user_id,
user_name
from user_table
where regexp_like (bizz_buzz,'^[^Z][^Y6]]' || q'[') AND
user_code not in ('A','E','I')
order by 1]';
Start at the beginning and search bizz_buzz
Match any one character that is NOT Z
Match any two characters that are not Y6
What's the ']' after the 6?
Then what?
I think that StackOverflow's formatting is causing some of the confusion in the answers. Oracle has a syntax for a string literal, q'[...]', which means that the ... portion is to be interpreted exactly as-is; so for instance it can include single quotes without having to escape each one individually.
But the code formatting here doesn't understand that syntax, so it is treating each single-quote as a string delimiter, which makes the result look different that how Oracle really sees it.
The expression is concatenating two such string literals together. (I'm not sure why - it looks like it would be possible to write this as a single string literal with no issues.) As pointed out in another answer/comment, the resulting SQL string is actually:
with cte as
select user_id,
user_name
from user_table
where regexp_like (bizz_buzz,'^[^Z][^Y6]') AND
user_code not in ('A','E','I')
order by 1
And also as pointed out in another answer, the [^Y6] portion of the regex matches a single character, not two. So this expression should simply match any string whose first character is not 'Z' and whose second character is neither 'Y' nor '6'.
When not in couples ] means... Well... Itself:
^[^Z][^Y6]]/
^ assert position at start of the string
[^Z] match a single character not present in the list below
Z the literal character Z (case sensitive)
[^Y6] match a single character not present in the list below
Y6 a single character in the list Y6 literally (case sensitive)
] matches the character ] literally
Start at the beginning and search bizz_buzz
Match any one character that is NOT Z
Match any two one characters that is not Y or 6
What's the ']' after the 6? it's a ]
I'm afraid I have to post this here as the comment section is inappropriate for the formatting required. After your edit above that shows the entire statement, I ran this to see what the string ends up being:
select q'[ with cte as
select user_id,
user_name
from user_table
where regexp_like (bizz_buzz,'^[^Z][^Y6]]' || q'[') AND
user_code not in ('A','E','I')
order by 1]' txt
from dual;
It ended up yielding this:
with cte as
select user_id,
user_name
from user_table
where regexp_like (bizz_buzz,'^[^Z][^Y6]') AND
user_code not in ('A','E','I')
order by 1
It is apparent now that the closing bracket and quote at the end of the regex belong to the first alternate quote string and not to the regex. This is concatenating 2 alternate quoted strings which is a tad confusing as it sure looked like part of the regex. If anything you are learning the importance of comments for the poor person behind you! Please comment this accordingly when you are done figuring this out. Even include a link to this post.

Postgresql : Pattern matching of values starting with "IR"

If I have table contents that looks like this :
id | value
------------
1 |CT 6510
2 |IR 52
3 |IRAB
4 |IR AB
5 |IR52
I need to get only those rows with contents starting with "IR" and then a number, (the spaces ignored). It means I should get the values :
2 |IR 52
5 |IR52
because it starts with "IR" and the next non space character is an integer. unlike IRAB, that also starts with "IR" but "A" is the next character. I've only been able to query all starting with IR. But other IR's are also appearing.
select * from public.record where value ilike 'ir%'
How do I do this? Thanks.
You can use the operator ~, which performs a regular expression matching.
e.g:
SELECT * from public.record where value ~ '^IR ?\d';
Add a asterisk to perform a case insensitive matching.
SELECT * from public.record where value ~* '^ir ?\d';
The symbols mean:
^: begin of the string
?: the character before (here a white space) is optional
\d: all digits, equivalent to [0-9]
See for more info: Regular Expression Match Operators
See also this question, very informative: difference-between-like-and-in-postgres

List of special characters for SQL LIKE clause

What is the complete list of all special characters for a SQL (I'm interested in SQL Server but other's would be good too) LIKE clause?
E.g.
SELECT Name FROM Person WHERE Name LIKE '%Jon%'
SQL Server:
%
_
[specifier] E.g. [a-z]
[^specifier]
ESCAPE clause E.g. %30!%%' ESCAPE '!' will evaluate 30% as true
' characters need to be escaped with ' E.g. they're becomes they''re
MySQL:
% - Any string of zero or more characters.
_ - Any single character
ESCAPE clause E.g. %30!%%' ESCAPE '!' will evaluate 30% as true
Oracle:
% - Any string of zero or more characters.
_ - Any single character
ESCAPE clause E.g. %30!%%' ESCAPE '!' will evaluate 30% as true
Sybase
%
_
[specifier] E.g. [a-z]
[^specifier]
Progress:
% - Any string of zero or more characters.
_ - Any single character
Reference Guide here [PDF]
PostgreSQL:
% - Any string of zero or more characters.
_ - Any single character
ESCAPE clause E.g. %30!%%' ESCAPE '!' will evaluate 30% as true
ANSI SQL92:
%
_
An ESCAPE character only if specified.
PostgreSQL also has the SIMILAR TO operator which adds the following:
[specifier]
[^specifier]
| - either of two alternatives
* - repetition of the previous item zero or more times.
+ - repetition of the previous item one or more times.
() - group items together
The idea is to make this a community Wiki that can become a "One stop shop" for this.
For SQL Server, from http://msdn.microsoft.com/en-us/library/ms179859.aspx :
% Any string of zero or more characters.
WHERE title LIKE '%computer%' finds all book titles with the word 'computer' anywhere in the book title.
_ Any single character.
WHERE au_fname LIKE '_ean' finds all four-letter first names that end with ean (Dean, Sean, and so on).
[ ] Any single character within the specified range ([a-f]) or set ([abcdef]).
WHERE au_lname LIKE '[C-P]arsen' finds author last names ending with arsen and starting with any single character between C and P, for example Carsen, Larsen, Karsen, and so on. In range searches, the characters included in the range may vary depending on the sorting rules of the collation.
[^] Any single character not within the specified range ([^a-f]) or set ([^abcdef]).
WHERE au_lname LIKE 'de[^l]%' all author last names starting with de and where the following letter is not l.
ANSI SQL92:
%
_
an ESCAPE character only if specified.
It is disappointing that many databases do not stick to the standard rules and add extra characters, or incorrectly enable ESCAPE with a default value of ‘\’ when it is missing. Like we don't already have enough trouble with ‘\’!
It's impossible to write DBMS-independent code here, because you don't know what characters you're going to have to escape, and the standard says you can't escape things that don't need to be escaped. (See section 8.5/General Rules/3.a.ii.)
Thank you SQL! gnnn
You should add that you have to add an extra ' to escape an exising ' in SQL Server:
smith's -> smith''s
Sybase :
% : Matches any string of zero or more characters.
_ : Matches a single character.
[specifier] : Brackets enclose ranges or sets, such as [a-f]
or [abcdef].Specifier can take two forms:
rangespec1-rangespec2:
rangespec1 indicates the start of a range of characters.
- is a special character, indicating a range.
rangespec2 indicates the end of a range of characters.
set:
can be composed of any discrete set of values, in any
order, such as [a2bR].The range [a-f], and the
sets [abcdef] and [fcbdae] return the same
set of values.
Specifiers are case-sensitive.
[^specifier] : A caret (^) preceding a specifier indicates
non-inclusion. [^a-f] means "not in the range
a-f"; [^a2bR] means "not a, 2, b, or R."
Potential answer for SQL Server
Interesting I just ran a test using LinqPad with SQL Server which should be just running Linq to SQL underneath and it generates the following SQL statement.
Records
.Where(r => r.Name.Contains("lkjwer--_~[]"))
-- Region Parameters
DECLARE #p0 VarChar(1000) = '%lkjwer--~_~~~[]%'
-- EndRegion
SELECT [t0].[ID], [t0].[Name]
FROM [RECORDS] AS [t0]
WHERE [t0].[Name] LIKE #p0 ESCAPE '~'
So I haven't tested it yet but it looks like potentially the ESCAPE '~' keyword may allow for automatic escaping of a string for use within a like expression.