Want to use Wild Card for declared variable in Case statement - sql

"AND" is in where clause of the query
Trying to use the Like operator in the "else" part
AND TCD.ANI = Case when #CallerID is null then TCD.ANI Else #CallerID end

Is this what you want?
AND (#CallerID is null OR TCD.ANI LIKE #CallerID)
I don't see many cases where CASE comes handy in conditions. Usually, things are simpler expressed with boolean logic.
Maybe you want to concatenate wildcards to the variable as well. In standard SQL, using string concatenation operator ||:
AND (#CallerID is null OR TCD.ANI LIKE '%' || #CallerID || '%')

Related

Using 'LIKE' in a CASE statement

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

Why "=" and "like" work in the same statement

I was practicing SQL injection skill, and I found that I could put = and LIKE in a single statement.
However, I'm not sure what does this mean and why it works?
SELECT 1 FROM users WHERE name='' LIKE '%'
So, what does that mean when I put = and LIKE in a statement, and when would I write something like this?
I am guessing that you are using MySQL, because this is syntactically correct in MySQL. It treats boolean types as numbers (which will be converted to integers and strings).
So, your code should be parsed as:
WHERE (name = '') LIKE '%'
This is because = and LIKE have the same precedence, and when operators have the same precedence, they are evaluated left-to-right (as explained in the documentation).
This, in turn evaluates to one of these three possibilities:
WHERE 1 LIKE '%' -- when name = ''
WHERE 0 LIKE '%' -- otherwise when name is not null
WHERE NULL like '%'
The first two will always evaluate to true. The third would discard any row where name is null.
(in MySQL and other popular DBMS) The LIKE operator is used to search for a specified pattern in a column. It admits "%" as a wildcard that represents zero, one, or multiple characters.
Your query always passes because the string '' meets this wildcard (zero characters). Incidentally, almost anything will. Some DBMS will react differently to such a query though.

Match Character Whether or Not It Exists in Like Statement

I need a like expression that will match a character whether or not it exists. It needs to match the following values:
..."value": "123456"...
..."value": "123456"...
"...value":"123456"...
This like statement will almost work: LIKE '%value":%"123456"%'
But there are values like this one that would also match, but I don't want returned:
..."value":"99999", "other":"123456"...
A regex expression to do what I'm looking to do is 'value": *?"123456"'. I need to do this in SQL Server 2008 and I don't believe there is good regex support in that version. How can I match using a like statement?
Remove the whitespace in your compare with REPLACE():
WHERE REPLACE(column,' ','') LIKE '%"value":"123456"%'
May need a double replace for tabs:
REPLACE(REPLACE(column,' ',''),' ','')
I don't think you can with the like operator. You could exclude ones you could match, like if you want to make sure it just doesn't contain other:
[field] LIKE '%value":%"123456"%` AND [field] NOT LIKE '%"other"%'
Otherwise I think you'd have to do some processing on the string. You could write a UDF to take the string and parse it to find the value for 'value' and compare based on that:
dbo.fn_GetValue([field], 'value') = '123456'
The function could find the index of '"' + #name + '"', find the next index of a quote, and the one after that, then get the string between those two quotes and return it.

How to use regex replace in Postgres function?

I have postgres function in which i am appending values in query such that i have,
DECLARE
clause text = '';
after appending i have some thing like,
clause = "and name='john' and age='24' and location ='New York';"
I append above in where clause of the query i already have. While executing query i am getting "and" just after "where" result in error
How to use regex_replace so that i remove the first "and" from clause before appending it to the query ?
Instead of fixing clause after the fact, you could avoid the problem by using
concat_ws (concatenate with separator):
clause = concat_ws(' and ', "name='john'", "age='24'", "location ='New York'")
will make clause equal to
"name='john' and age='24' and location ='New York'"
This can be even simpler. Use right() with a negative offset.
Truncates the first n characters and you don't need to specify the length of the string. Faster, simpler.
Double quotes (") are for identifiers in Postgres (and standard SQL) and incorrect in your example. Enclose string literals in single quotes (') and escape single quotes within - or use dollar quoting:
Insert text with single quotes in PostgreSQL
Since this is a plpgsql assignment, use the proper assignment operator :=. The SQL assignment operator = is tolerated, too, but can lead to ambiguity in corner cases.
Finally, you can assign a variable in plpgsql at declaration time. Assignments in plpgsql are still cheap but more expensive than in other programming languages.
DECLARE
clause text := right($$and name='john' and age='24' ... $$, -5)
All that said, it seems like you are trying to work with dynamic SQL and starting off on the wrong foot here. If those values can change, rather supply them as values with the USING clause of EXECUTE and be wary of SQL injection. Read some of the related questions and answers on the matter:
https://stackoverflow.com/search?q=[plpgsql]+[dynamic-sql]+EXECUTE+USING
You do not need regex:
clause = substr(clause, 5, 10000);
clause = substr(clause, 5, length(clause)- 4); -- version for formalists
concat_ws sounds like the best option, but as a general solution for things like this (or any sort of list with a delimiter) you can use logic like (pseudocode):
delim = '';
while (more appendages)
clause = delim + nextAppendage;
delim = ' AND ';
If you want to do it with regular expression try this:
result = regexp_replace(clause, '^and ', '')

Use '=' or LIKE to compare strings in SQL?

There's the (almost religious) discussion, if you should use LIKE or '=' to compare strings in SQL statements.
Are there reasons to use LIKE?
Are there reasons to use '='?
Performance? Readability?
LIKE and the equality operator have different purposes, they don't do the same thing:
= is much faster, whereas LIKE can interpret wildcards. Use = wherever you can and LIKE wherever you must.
SELECT * FROM user WHERE login LIKE 'Test%';
Sample matches:
TestUser1
TestUser2
TestU
Test
To see the performance difference, try this:
SELECT count(*)
FROM master..sysobjects as A
JOIN tempdb..sysobjects as B
on A.name = B.name
SELECT count(*)
FROM master..sysobjects as A
JOIN tempdb..sysobjects as B
on A.name LIKE B.name
Comparing strings with '=' is much faster.
In my small experience:
"=" for Exact Matches.
"LIKE" for Partial Matches.
There's a couple of other tricks that Postgres offers for string matching (if that happens to be your DB):
ILIKE, which is a case insensitive LIKE match:
select * from people where name ilike 'JOHN'
Matches:
John
john
JOHN
And if you want to get really mad you can use regular expressions:
select * from people where name ~ 'John.*'
Matches:
John
Johnathon
Johnny
Just as a heads up, the '=' operator will pad strings with spaces in Transact-SQL. So 'abc' = 'abc ' will return true; 'abc' LIKE 'abc ' will return false. In most cases '=' will be correct, but in a recent case of mine it was not.
So while '=' is faster, LIKE might more explicitly state your intentions.
http://support.microsoft.com/kb/316626
For pattern matching use LIKE. For exact match =.
LIKE is used for pattern matching and = is used for equality test (as defined by the COLLATION in use).
= can use indexes while LIKE queries usually require testing every single record in the result set to filter it out (unless you are using full text search) so = has better performance.
LIKE does matching like wildcards char [*, ?] at the shell
LIKE '%suffix' - give me everything that ends with suffix. You couldn't do that with =
Depends on the case actually.
There is another reason for using "like" even if the performance is slower: Character values are implicitly converted to integer when compared, so:
declare #transid varchar(15)
if #transid != 0
will give you a "The conversion of the varchar value '123456789012345' overflowed an int column" error.