SQL match on letter and number arrangement - sql

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.

Related

Using Regex to determine what kind of SQL statement a row is from a list?

I have a large list of SQL commands such as
SELECT * FROM TEST_TABLE
INSERT .....
UPDATE .....
SELECT * FROM ....
etc. My goal is to parse this list into a set of results so that I can easily determine a good count of how many of these statements are SELECT statements, how many are UPDATES, etc.
so I would be looking at a result set such as
SELECT 2
INSERT 1
UPDATE 1
...
I figured I could do this with Regex, but I'm a bit lost other than simply looking at everything string and comparing against 'SELECT' as a prefix, but this can run into multiple issues. Is there any other way to format this using REGEX?
You can add the SQL statements to a table and run them through a SQL query. If the SQL text is in a column called SQL_TEXT, you can get the SQL command type using this:
upper(regexp_substr(trim(regexp_replace(SQL_TEXT, '\\s', ' ')),
'^([\\w\\-]+)')) as COMMAND_TYPE
You'll need to do some clean up to create a column that indicates the type of statement you have. The rest is just basic aggregation
with cte as
(select *, trim(lower(split_part(regexp_replace(col, '\\s', ' '),' ',1))) as statement
from t)
select statement, count(*) as freq
from cte
group by statement;
SQL is a language and needs a parser to turn it from text into a structure. Regular expressions can only do part of the work (such as lexing).
Regular Expression Vs. String Parsing
You will have to limit your ambition if you want to restrict yourself to using regular expressions.
Still you can get some distance if you so want. A quick search found this random example of tokenizing MySQL SQL statements using regex https://swanhart.livejournal.com/130191.html

DB2 LIKE matching Pattern

My question is simple.
In a DB2 Database, I have my table
Table (Id integer, name varchar)
I want to select entries which names like 'ac1%' or 'ac2%' or 'ac3%', so which names match regex
'^ac[123]*'
Is there any method to have this select query without write :
WHERE name LIKE 'ac1%' OR name LIKE 'ac2%' OR name LIKE 'ac2%'
Probably the most efficient method is:
where name >= 'ac1' and
name < 'ac4'
You can also use regular expressions:
where regexp_like(name, '^ac[1-3]')
Depending on your Db2-server platform (Z/OS, i-Series, Linux/Unix/Windows) and Db2-version, you can use REGEXP_LIKE function. This allows regular expressions in SQL.
See documentation and examples here.
i think below will work cause REGEXP_LIKE(col,'[0-9]{3}-[0-9]{3}-[0-9]{2}') will always return true if col contain any of 0 to 9 value
SELECT * FROM table1
WHERE REGEXP_LIKE(name,'[1-3]')

Verify if the second character is a letter in SQL

I want to put a condition in my query where I have a column that should contain second position as an alphabet.
How to achieve this?
I've tried with _[A-Z]% in where clause but is not working. I've also tried [A-Z]%.
Any inputs please?
I think you want mysql query. like this
SELECT * FROM table WHERE column REGEXP '^.[A-Za-z]+$'
or sql server
select * from table where column like '_[a-zA-Z]%'
You can use regular expression matching in your query. For example:
SELECT * FROM `test` WHERE `name` REGEXP '^.[a-zA-Z].*';
That would match the name column from the test table against a regex that verifies if the second character is either a lowercase or uppercase alphabet letter.
Also see this SQL Fiddle for an example of data it does and doesn't match.
agree with #Gordon Linoff, your ('_[A-Z]%') should work.
if not work, kindly add some sample data with your question.
Declare #Table Table
(
TextCol Varchar(20)
)
Insert Into #Table(TextCol) Values
('23423cvxc43f')
,('2eD97S9')
,('sAgsdsf')
,('3Ss08008')
Select *
From #Table As t
Where t.TextCol Like '_[A-Z]%'
The use of '%[A-Z]%' suggests that you are using SQL Server. If so, you can do this using LIKE:
where col like '_[A-Z]%'
For LIKE patterns, _ represents any character. If the first character needs to be a digit:
where col like '[0-9][A-Z]%'
EDIT:
The above doesn't work in DB2. Instead:
where substr(col, 2, 1) between 'A' and 'Z'

MSSQL Regular expression

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/.]+$')

Can SQL SUM() function take an expression as argument?

I'm using SQLite database and I'm wondering whether I'm allowed to write queries as follows:
SELECT SUM(column1 * column2)
FROM my_table;
I googled but references say that SUM function is has the following format:
SUM([DISTINCT|ALL] column)
And my question is: does column mean actually column or does it allow expressions (like above) too?
You can always use a table expression:
SELECT SUM(Calc)
FROM (
SELECT Column1 * Column2 AS 'Calc'
FROM My_Table) t
I don't have SQLite but checking the docs indicates this should work fine.
Yes, you can use an expression like the one you mentioned, if the datatype of both columns allow it.