Using 'LIKE' in a CASE statement - sql

I am attempting to generate a new field based on an existing field where some of the entries contain different special characters. (ie. *, ') The special characters are at the end of the string, which is either second or third position.
I am NEW to SQL but not new to data. I am using a CASE WHEN statement. I have tried several approaches and several other commands within the CASE statement.
what I want is:
SELECT *
CASE WHEN grde_code_mid LIKE '[*]' THEN 'Remedial'
WHEN grde_code_mid LIKE '[']' THEN 'Continuing'
ELSE NULL
END AS class_type
FROM grde_tble
I keep getting the same error: "FROM keyword not found where expected". I expect to have all 3 returns in the new field.

If you're looking for ' character you should escape it.
Change
WHEN grde_code_mid LIKE '[']' THEN 'Continuing'
by
WHEN grde_code_mid LIKE '['']' THEN 'Continuing'
Have a look at this question: How do I escape a single quote in SQL Server?

There are several issues with your query:
you are missing a comma in the SELECT clause between * and the CASE expression (this is causing the error that you are currently getting)
the bracket notations is only supported in SQL-Server; if you want to match on strings that end with * in a portable manner, you need expression ... LIKE '%*', not LIKE '[*]'
single quotes embedded in a string need to be escaped
SELECT *, other_field FROM ... is not supported on all RDBMS (and, as commented by jarhl, actually isn't standard ANSI SQL notation); you usually need to prefix the * with the table name or alias
Consider:
SELECT
g.*,
CASE
WHEN grde_code_mid LIKE '%*' THEN 'Remedial'
WHEN grde_code_mid LIKE '%''' THEN 'Continuing'
ELSE NULL
END AS class_type
FROM grde_tble g

Thank you all. I am still getting the hang of the language and proper terms. I am using Oracle DB. Also, yes, I did need to reference the table in the select statement (SELECT tablename.*). Found a work around:
CASE WHEN regexp_like(grde_code_mid, '[*]') THEN 'Remedial'
WHEN regexp_like(grde_code_mid, '['']') THEN 'Continuing'
ELSE NULL END AS special_class

Related

How run Select Query with LIKE on thousands of rows

Newbie here. Been searching for hours now but I can seem to find the correct answer or properly phrase my search.
I have thousands of rows (orderids) that I want to put on an IN function, I have to run a LIKE at the same time on these values since the columns contains json and there's no dedicated table that only has the order_id value. I am running the query in BigQuery.
Sample Input:
ORD12345
ORD54376
Table I'm trying to Query: transactions_table
Query:
SELECT order_id, transaction_uuid,client_name
FROM transactions_table
WHERE JSON_VALUE(transactions_table,'$.ordernum') LIKE IN ('%ORD12345%','%ORD54376%')
Just doesn't work especially if I have thousands of rows.
Also, how do I add the order id that I am querying so that it appears under an order_id column in the query result?
Desired Output:
Option one
WITH transf as (Select order_id, transaction_uuid,client_name , JSON_VALUE(transactions_table,'$.ordernum') as o_num from transactions_table)
Select * from transf where o_num like '%ORD12345%' or o_num like '%ORD54376%'
Option two
split o_num by "-" as separator , create table of orders like (select 'ORD12345' as num
Union
Select 'ORD54376' aa num) and inner join it with transf.o_num
One method uses OR:
WHERE JSON_VALUE(transactions_table, '$.ordernum') LIKE IN '%ORD12345%' OR
JSON_VALUE(transactions_table, '$.ordernum') LIKE '%ORD54376%'
An alternative method uses regular expressions:
WHERE REGEXP_CONTAINS(JSON_VALUE(transactions_table, '$.ordernum'), 'ORD12345|ORD54376')
According to the documentation, here, the LIKE operator works as described:
Checks if the STRING in the first operand X matches a pattern
specified by the second operand Y. Expressions can contain these
characters:
A percent sign "%" matches any number of characters or
bytes.
An underscore "_" matches a single character or byte.
You can escape "\", "_", or "%" using two backslashes. For example, "\%". If
you are using raw strings, only a single backslash is required. For
example, r"\%".
Thus , the syntax would be like the following:
SELECT
order_id,
transaction_uuid,
client_name
FROM
transactions_table
WHERE
JSON_VALUE(transactions_table,
'$.ordernum') LIKE '%ORD12345%'
OR JSON_VALUE(transactions_table,
'$.ordernum') LIKE '%ORD54376%
Notice that we specify two conditions connected with the OR logical operator.
As a bonus information, when querying large datasets it is a good pratice to select only the columns you desire in your out output ( either in a Temp Table or final view) instead of using *, because BigQuery is columnar, one of the reasons it is faster.
As an alternative for using LIKE, you can use REGEXP_CONTAINS, according to the documentation:
Returns TRUE if value is a partial match for the regular expression, regex.
Using the following syntax:
REGEXP_CONTAINS(value, regex)
However, it will also work if instead of a regex expression you use a STRING between single/double quotes. In addition, you can use the pipe operator (|) to allow the searched components to be logically ordered, when you have more than expression to search, as follows:
where regexp_contains(email,"gary|test")
I hope if helps.

Similar to with regex in Postgresql

In Postgresql database I have a column called names where I have some names which need to be parsed using regex to clean up punctuation parts. I am able to get a clean name using regexp_replace as follows:
select regexp_replace(name,'\.COM|''[A-Z]|[^a-zA-Z0-9 -]+|\s(?=&)|(?<!\w\w)(?:\s+|-)(?!\w\w)','','g')
from tableA
However, I would like to compare with some strings that are also cleaned of punctuation. How can I use similar to with the formed regular expression?
select name
from tableA
where (lower(name) ~ '\.COM|''[A-Za-z]|[^a-zA-Z0-9 -]+|\s(?=&)|(?<!\w\w)(?:\s+|-)(?!\w\w)') as nameParsed similar to '(fg )%' and
(lower(name) ~ '\.COM|''[A-Za-z]|[^a-zA-Z0-9 -]+|\s(?=&)|(?<!\w\w)(?:\s+|-)(?!\w\w)') as nameParsed similar to '%( cargo| carrier| cartage )%'
With the previous query I am getting this error:
LINE 3: ...-zA-Z0-9 -]+|\s(?=&)|(?<!\w\w)(?:\s+|-)(?!\w\w)') as namePar...
I have tried in where clause like this and it seems to be working:
select name
from tableA
where (select lower(regexp_replace(name,'\.COM|''[A-Z]|[^a-zA-Z0-9 -]+|\s(?=&)|(?<!\w\w)(?:\s+|-)(?!\w\w)','','g'))) similar to '(fg )%'
Is this the best approach? The execution time went to 46 seconds :(
Thanks in advance
You're trying to get a column name in a WHERE clause (is a comparison, not a column). So, you can use as follows:
SELECT name
FROM "tableA"
WHERE (regexp_replace(name,'\.COM|''[A-Z]|[^a-zA-Z0-9 -]+|\s(?=&)|(?<!\w\w)(?:\s+|-)(?!\w\w)','','g') similar to '(fg )%'
OR regexp_replace(name,'\.COM|''[A-Z]|[^a-zA-Z0-9 -]+|\s(?=&)|(?<!\w\w)(?:\s+|-)(?!\w\w)','','g') similar to '%( cargo| carrier| cartage )%');
Alternatively, you can use ilike instead of similar to if you want to find a specific word.

Regular Expression Pattern for Search in SQL

I want to search a table which has file name(s) with a {Numerical Pattern String}.PDF.
Example: 1.PDF, 12.PDF, 123.PDF 1234.PDF etc.....
select * from web_pub_subfile where file_name like '[0-9]%[^a-z].pdf'
But above SQL Query is resulting even these kind of files
1801350 Ortho.pdf
699413.processing2.pdf
15-NOE-301.pdf
Could any one help me what I am missing here.
One way to do it is getting the substring before the file extension and checking if it is numeric. This solution only works well if there is only one . character in the file name.
select * from web_pub_subfile
where isnumeric(left(file_name,charindex('.',file_name)-1)) = 1
Note:
ISNUMERIC returns 1 for some characters that are not numbers, such as plus (+), minus (-), and valid currency symbols such as the dollar sign ($).
To handle file names with mutliple . characters and if there is always a .filetype extension, use
select * from web_pub_subfile
where isnumeric(left(file_name,len(file_name)-charindex('.',reverse(file_name)))) = 1
and charindex('.',file_name) > 0
Sample demo
As suggested by #Blorgbeard in the comments, to avoid the use of isnumeric, use
select * from web_pub_subfile
where left(file_name,len(file_name)-charindex('.',reverse(file_name))) NOT LIKE '%[^0-9]%'
and len(left(file_name,len(file_name)-charindex('.',reverse(file_name)))) > 0
You can't really do what you are trying to do using plain out of the box sql. The reason you are seeing those results is that the % character matches any character, any number of times. It's not like * in a regex which matches the pervious character 0 or more times.
Your best option would probably be to create some CLR functions that implement regex functionality on the SQL Server side. You can take a look at this link to find a good place to start.
Depending on your version if 2012+, you could use Try_Convert()
select * from web_pub_subfile where Try_Convert(int,replace(file_name,'.pdf',''))>0
Declare #web_pub_subfile table (file_name varchar(100))
Insert Into #web_pub_subfile values
('1801350 Ortho.pdf'),
('699413.processing2.pdf'),
('15-NOE-301.pdf'),
('1.pdf'),
('1234.pdf')
select * from #web_pub_subfile where Try_Convert(int,replace(file_name,'.pdf',''))>0
Returns
file_name
1.pdf
1234.pdf

How to escape square bracket when using LIKE? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
SQL Server LIKE containing bracket characters
I am having a problem with pattern matching.I have created two objects say,with codes
1)[blah1]
2)[blah2] respectively
in the search tab,suppose if i give "[blah" as the pattern,its returning all the strings
i.e., [blah1] and [blah2]
The query is
select *
from table1
where code like N'%[blah%'
I guess the problem is with the condition and special characters. Please do revert if you have as solution. Is there any solution where we can escape the character"[". I tried to change the condition as N'%[[blah%'.But even then its returning all the objects that is in the table.
When you don't close the square bracket, the result is not specified.
However, the story is different when you close the bracket, i.e.
select *
from table1
where code like N'%[blah%]%'
In this case, it becomes a match for (any) + any of ('b','l','a','h','%') + (any). For SQL Server, you can escape characters using the ESCAPE clause.
select * from table1 where code like N'%\[blah%\]%' escape '\'
SQL Fiddle with examples
You can escape a literal bracket character this way:
select *
from table1
where code like N'%[[]blah%'
Source: LIKE (Transact-SQL), under the section "Using Wildcard Characters As Literals."
I guess this is Microsoft's way of being consistent, since they use brackets to delimit table and column identifiers too. But the use of brackets is not standard SQL. For that matter, bracket as a metacharacter in LIKE patterns is not standard SQL either, so it's not necessary to escape it at all in other brands of database.
As per My understanding, the symbol '[', there is no effect in query. like if you query with symbol and without symbol it shows same result.
Either you can skip the unwanted character at UI Level.
select * from table1 where code like '%[blah%'
select * from table1 where code like '%blah%'
Both shows same result.

Replacing an Unknown Value with SQL Replace

I'm probably missing something really obvious here, but this has been a bear to search for on Google (Maybe I don't have the right terminology).
I want to replace an unknown value with another value from a temp table. I know the length of the value so my thought was to use underscores as you would in a LIKE statement. The following DOES NOT work however:
UPDATE MyTable
SET Name =
Replace(Name, '__SomeString', TempTable.value + ' SomeString')
FROM MyTable INNER JOIN TempTable
ON Name LIKE TempTable.Name
This is MS SQL 2000 FWIW.
EDIT: To try and clarify it looks like the underscore '_' wildcard that is used in a LIKE statement is taken literally inside of the replace function. Is there another way?
Any thoughts?
UPDATE MyTable
SET Name =
CASE WHEN (Name like '_SomeString')
THEN TempTable.value + SUBSTRING(Name,2,LEN(Name)-1)
ELSE Name END
FROM MyTable INNER JOIN TempTable
ON MyTable.Name = TempTable.Name
WHERE MyTable.Name = 'TheNameToReplace' -- I don't know if it will be for a specific name hence the where...
This will then replace 'SomeString' in the Name field, with the value from TempTable.value
Is this what you were looking for or something else?
Perhaps you can use stuff instead of replace. You need to know the start position in the string where you want to replace the characters and you need to know the length of the expression that is to be replaced. If you don't know that perhaps you can use charindex or patindex to figure that out.
select stuff('A123', 1, 1, 'B ')
Result:
(No column name)
B 123
Would somethi8ng like this work?
UPDATE mytable
SET field1 = 'A' + SUBSTRING(field1,2,LEN(field1))
WHERE LEFT(field1) IN (0,1,2,3,4,5,6,7,8,9)
Apparently it is not possible to use wild cards in the REPLACE function. This is the closest match on SO that I could find: MySQL Search & Replace with WILDCARDS - Query While the link is for MySQL I believe it is true for MS SQL as well.
The other answers here are all creative solutions to the problem, but I ended up going the brute force route.