MSSQL Regular expression - sql

I have the following REGEX: ^[-A-Za-z0-9/.]+$
This currently checks whether the value entered into a textbox matches this. If not, it throws an error.
I need to check whether anything has already gone into the database that doesnt match this.
I have tired:
SELECT * FROM *table* WHERE ([url] NOT LIKE '^[-A-Za-z0-9/.]+$')
SELECT * FROM *table* WHERE PATINDEX ('^[-A-Za-z0-9/.]+$', [url])
UPDATE
So after a bit of research I've realised I don't think I can use REGEXP.
I thought I could do something like this? Its not giving me the expected results but its running unlike anything else. Can anyone spot anything wrong with it?
SELECT *,
CASE WHEN [url] LIKE '^[-A-Za-z0-9/.]+$'
THEN 'Match'
ELSE 'No Match'
END Validates
FROM
*table*

This is what I have used in the end:
SELECT *,
CASE WHEN [url] NOT LIKE '%[^-A-Za-z0-9/.+$]%'
THEN 'Valid'
ELSE 'No valid'
END [Validate]
FROM
*table*
ORDER BY [Validate]

Disclaimer: The original question was about MySQL. The SQL Server answer is below.
MySQL
In MySQL, the regex syntax is the following:
SELECT * FROM YourTable WHERE (`url` NOT REGEXP '^[-A-Za-z0-9/.]+$')
Use the REGEXP clause instead of LIKE. The latter is for pattern matching using % and _ wildcards.
SQL Server
Since you made a typo, and you're using SQL Server (not MySQL), you'll have to create a user-defined CLR function to expose regex functionality.
Take a look at this article for more details.

As above the question was originally about MySQL
Use REGEXP, not LIKE:
SELECT * FROM `table` WHERE ([url] NOT REGEXP '^[-A-Za-z0-9/.]+$')

Related

Like operator condition in postgresql data issue

I have below data in the table
HJ-DEF-ABCF010-ABC18-09-17-D
GHJ-ABC-ABFV006-ABC18-09-18-R
OH-DEF-ABFCRT2037-ABC17-01-18-R
I want to populate the value in another column like
HJ-DEF-ABCF010-ABC18-09-17-D BET
GHJ-ABC-ABFV006-ABD18-09-18-R BET
OH-DEF-ABFCRT2037-ABCD17-01-18-R BET
As the mapping for
ABC18 is BET
ABD18 is BET
ABCD17 is BET
I was using the below sql query for that
select col1,case
when col1 like '%-ABC[1-2][0-9]-%' then BET
when col1 like '%-ABD[1-2][0-9]-%' then BET
when col1 like '%-ABCD[1-2][0-9]-%' then BET
else - end form table
which is working fine in SQl sever but in Pogresql we can't use [1-2] to find out the expected digit in the position. Any suggestion or idea how to achieve in Posgresql.
It works just fine. However, you think -- for some reason -- that LIKE supports character classes and other regular-expression-like features. That is simply not true in Postgres, nor in any other database other than SQL Server, Sybase, and MS Access.
Just use regular expressions.
For the original version:
SELECT *
FROM Customers
WHERE Customerid ~ '^[1-2][1-1]';
For the edited version:
SELECT *
FROM Customers
WHERE Customerid ~ '[-].{3}[1-2]1';
You can actually make your current logic work with LIKE, with a bit of effort:
SELECT *
FROM Customers
WHERE Customerid LIKE '11%' OR Customerid LIKE '21%';
You seem to be using perhaps SQL Server or Sybase enhanced LIKE syntax. Postgres does not support this, but it does support its own ~ regex operator. See Gordon's answer for more on that.
The edit to your question can use this:
SELECT *
FROM Customers
WHERE Customerid ~ '-[^-]{3}[1-2]7';
Demo
Used with SIMILAR TO instead of like. select col1,case when col1 SIMILAR TO '%-AB([CD]|CD)[1-2][0-9]-%' then BET else - end form table thnx #WiktorStribiżew

SQL query using CONTAINS doesn't work on specify keyword

I am writing a simple query in SQL Server:
SELECT *
FROM Table1
WHERE CONTAINS(Column1, 'MY')
but it doesn't return any results. While using like it returns results.
Is there any specific reason why the keyword 'MY' doesn't work?
Update:
If I use other keywords, it works, only the specific 'MY' seems to be that I cannot used. My column is already set into fulltext index. Also for performance purposes I prefer to use CONTAINS.
you could do something like
select * from Table1 where Column1 like '%MY%'
When you use linq you can use the statements like you use in C#. It will be translated to SQL, a language which database can execute. So, try something like this:
string sql = "SELECT * FROM Table1 WHERE Column1 like #Column1";
And in your command, try to add parameters to replace the #Column1
command.Parameters.AddWithValue("#Column1", "%MY%");
The % char, represents anything. So, if you want to do a command like StartWith like we do from string, just use MY%.

SQL match on letter and number arrangement

Is it possible to write an SQL statement which finds all rows which match a specific arrangement of letters/numbers?
i.e. SELECT myCol FROM myTable WHERE myCol='<letter><letter><number>'
Should return 12X and 34Y but not 123X or 34YY
I am using MySQL.
I haven't got MySQL on this machine to test but I think
SELECT myCol
FROM myTable
WHERE myCol REGEXP '^[0-9][0-9][A-Z]$'
Should do it. ^ is an anchor for start of string, $ for end of string and the rest should be self explanatory.
Looks like you could also use REGEXP '^[[:digit:]][[:digit:]][[:alpha:]]$' but completely untested and just going off the docs.
Many database management systems support regular expressions. So, in PostgreSQL 9.x for example, you can do this . . .
create table mytable (
mycol varchar(10) primary key
);
insert into mytable values
('12X'),
('34Y'),
('123X'),
('34YY');
And then
select *
from mytable
where mycol ~ ('^[0-9][0-9][A-Z]$');
And Oracle's version.. here it is:
SELECT myCol
FROM myTable
WHERE REGEXP_LIKE(myCol, '^\d{2}[A-Z]$')
For sql server, you can use with PATINDEX. For mysql, you have REGEXP.
EDIT : Damien_The_Unbeliever pointed out I was wrong and that PATINDEX does not support regular expressions. That's correct but after some googling I found that you can use regular expressions in sql server because it hosts CLR.

Use like in T-SQl to search for words separated by an unknown number of spaces

I have this query:
select * from table where column like '%firstword[something]secondword[something]thirdword%'
What do I replace [something] with to match an unknown number of spaces?
Edited to add: % will not work as it matches any character, not just spaces.
Perhaps somewhat optimistically assuming "unknown number" includes zero.
select *
from table where
REPLACE(column_name,' ','') like '%firstwordsecondwordthirdword%'
The following may help: http://blogs.msdn.com/b/sqlclr/archive/2005/06/29/regex.aspx
as it describes using regular expressions in SQL queries in SQL Server 2005
I would definitely suggest cleaning the input data instead, but this example may work when you call it as a function from the SELECT statement. Note that this will potentially be very expensive.
http://www.bigresource.com/MS_SQL-Replacing-multiple-spaces-with-a-single-space-9llmmF81.html

Make an SQL request more efficient and tidy?

I have the following SQL query:
SELECT Phrases.*
FROM Phrases
WHERE (((Phrases.phrase) Like "*ing aids*")
AND ((Phrases.phrase) Not Like "*getting*")
AND ((Phrases.phrase) Not Like "*contracting*"))
AND ((Phrases.phrase) Not Like "*preventing*"); //(etc.)
Now, if I were using RegEx, I might bunch all the Nots into one big (getting|contracting|preventing), but I'm not sure how to do this in SQL.
Is there a way to render this query more legibly/elegantly?
Just by removing redundant stuff and using a consistent naming convention your SQL looks way cooler:
SELECT *
FROM phrases
WHERE phrase LIKE '%ing aids%'
AND phrase NOT LIKE '%getting%'
AND phrase NOT LIKE '%contracting%'
AND phrase NOT LIKE '%preventing%'
You talk about regular expressions. Some DBMS do have it: MySQL, Oracle... However, the choice of either syntax should take into account the execution plan of the query: "how quick it is" rather than "how nice it looks".
With MySQL, you're able to use regular expression where-clause parameters:
SELECT something FROM table WHERE column REGEXP 'regexp'
So if that's what you're using, you could write a regular expression string that is possibly a bit more compact that your 4 like criteria. It may not be as easy to see what the query is doing for other people, however.
It looks like SQL Server offers a similar feature.
Sinec it sounds like you're building this as you go to mine your data, here's something that you could consider:
CREATE TABLE Includes (phrase VARCHAR(50) NOT NULL)
CREATE TABLE Excludes (phrase VARCHAR(50) NOT NULL)
INSERT INTO Includes VALUES ('%ing aids%')
INSERT INTO Excludes VALUES ('%getting%')
INSERT INTO Excludes VALUES ('%contracting%')
INSERT INTO Excludes VALUES ('%preventing%')
SELECT
*
FROM
Phrases P
WHERE
EXISTS (SELECT * FROM Includes I WHERE P.phrase LIKE I.phrase) AND
NOT EXISTS (SELECT * FROM Excludes E WHERE P.phrase LIKE E.phrase)
You are then always just running the same query and you can simply change what's in the Includes and Excludes tables to refine your searches.
Depending on what SQL server you are using, it may support REGEX itself. For example, google searches show that SQL Server, Oracle, and mysql all support regex.
You could push all your negative criteria into a short circuiting CASE expression (works Sql Server, not sure about MSAccess).
SELECT *
FROM phrases
WHERE phrase LIKE '%ing aids%'
AND CASE
WHEN phrase LIKE '%getting%' THEN 2
WHEN phrase LIKE '%contracting%' THEN 2
WHEN phrase LIKE '%preventing%' THEN 2
ELSE 1
END = 1
On the "more efficient" side, you need to find some criteria that allows you to avoid reading the entire Phrases column. Double sided wildcard criteria is bad. Right sided wildcard criteria is good.