What does command LIKE '[atoz:a]%' mean in SQL Server? - sql

I've inherited a database and application from a project and I'm trying to debug a problem with a database query.
There's a line in the query that reads:
WHERE property_title LIKE '[atoz:a]%'
I'm struggling to understand what the atoz command is doing as I've never come across it before - I assumed it was stating that it would only allow characters in the title - but some of the titles contain symbols such as () or -
I've tried searching for it on Google but I must be using the wrong terminology as nothing is appearing. If someone could explain it to me, or point me to a resource that would be great!
Thanks

This is looking for property_title that starts with the letters "a", "t", "o", "z" and ":". The second "a" is redundant.
I would guess the intention is actually:
WHERE property_title LIKE '[a-z]%'
which would specify that the property title starts with a letter (or a lower case letter, depending on the collation being used).

This is just part of the LIKE operator of T-SQL:
[ ]
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.
The exact expression you're seeing:
'[atoz:a]%'
basically means this:
First any single character that can be one of the following:
a, t, o, z, or :
Then followed by anything (even nothing)
Note that atoz does not mean any character from a to z, it literally means the 4 characters a, t, o and z. To get any character from a to z you would use [a-z]. The second a in the expression is redundant, as [aa] means the same as [a].

Related

Snowflake - Check if 1st 3 Characters of string are letters

Am trying to determine how one attempts to identify, in Snowflake SQL, if a product code begins with three letters.
Suggestions?
I did just try: LEFT(P0.PRODUCTCODE,3) NOT LIKE '[a-zA-Z]%' but it didn't work.
Thanks folks
You can use REGEXP_LIKE to return a boolean value indicating whether or not your string matched the pattern you're interested in.
In your case, something like REGEXP_LIKE(string_field_here, '[a-zA-Z]{3}.*')
Breaking down the regular expression pattern:
[a-zA-Z]: Only match letter characters, both upper and lowercase
{3}: Require three of those letters
.*: Allow any number of any characters after those three letters
Note: in many cases, you would need to specifically indicate the beginning/ending of the string in the pattern, but Snowflake's implementation handles that for you. From the docs:
The function implicitly anchors a pattern at both ends (i.e. ''
automatically becomes '^$', and 'ABC' automatically becomes '^ABC$').
To match any string starting with ABC, the pattern would be 'ABC.*'.
You can try running these examples:
SELECT REGEXP_LIKE('abc', '[a-zA-Z]{3}.*') AS _abc,
REGEXP_LIKE('123', '[a-zA-Z]{3}.*') AS _123,
REGEXP_LIKE('abc123', '[a-zA-Z]{3}.*') AS _abc123,
REGEXP_LIKE('123abc', '[a-zA-Z]{3}.*') AS _123abc

Velocity / Marketo issue with if statements that include a space

I am writing some Velocity Script as part of a Marketo email template that requires that I check if an boolean attribute on a lead is set or not.
When I attempt to display something associated with a lead in my system I can do something like;
{{lead.myName}}
This also works for fields that have spaces in them;
{{lead.my name}}
When it comes to using that field for #setting or #ifing something then it doesn't work as well.
#if($lead.my name) throws an error saying that an unexpected space has been found.
I have tried variants like #if(${lead.my name}) to no avail.
Any help / pointers would be massively helpful.
Actual use case
In my example the field I need to access is called lead.Subscribed to Innovation (L) 1, I don't think the brackets will cause a problem, certainly any error messages have been space related.
According to User Guide variables cannot have spaces
A VTL Identifier must start with an alphabetic character (a .. z or A .. Z). The rest of the characters are limited to the following types of characters:
alphabetic (a .. z, A .. Z)
numeric (0 .. 9)
hyphen ("-")
underscore ("_")
even with the curly brackets :
this is valid:
#set( ${myemail} = "email#email.com" )
while trhis is invalid:
#set( ${my email} = "email#email.com" )
My best guess will be to change the source system to comply with the velocity naming convention.

Using SQL like for pattern query

I have a PHP function that accepts a parameter called $letter and I want to set the default value of the parameter to a pattern which is "any number or any symbol". How can I do that?
This is my query by the way .
select ID from $wpdb->posts where post_title LIKE '".$letter."%
I tried posting at wordpress stackexchange and they told me to post it here as this is an SQL/general programming question that specific to wordpress.
Thank you! Replies much appreciated :)
In order to match just numbers or letters (I'm not sure exactly what you mean by symbols) you can use the RLIKE operator in MySQL:
SELECT ... WHERE post_title RLIKE '^[A-Za-z0-9]'
That means by default $letter would be [A-Za-z0-9] - this means all letters from a to z (both cases) and numbers from 0-9. If you need specific symbols you can add them to the list (but - has to be first or last, since otherwise it has a special meaning of range). The ^ character tells it to be at the beginning of the string. So you will need something like:
"select ID from $wpdb->posts where post_title RLIKE '^".$letter."%'"
Of course I have to warn you against SQL injection attacks if you build your query like this without sanitizing the input (making sure it doesn't have any ' (apostrophe) in it.
Edit
To match a title that starts with a number just use [0-9] - that means it will match one digit from 0 to 9

SQL to return results for the following regex

I have the following regular expression:
WHERE A.srvc_call_id = '40750564' AND REGEXP_LIKE (A.SRVC_CALL_DN, '[^TEST]')
The row that contains 40750564 has "TEST CALL" in the column SRVC_CALL_DN and REGEXP_LIKE doesn't seem to be filtering it out. Whenever I run the query it returns the row when it shouldn't.
Is my regex pattern wrong? Or does SQL not accept [^whatever]?
The carat anchors the expression to the start of a string. By enclosing the letters T, E, S & T in square brackets you're searching, as barsju suggests for any of these characters, not for the string TEST.
You say that SRVC_CALL_DN contains the string 'TEST CALL', but you don't say where in the string. You also say that you're looking for where this string doesn't match. This implies that you want to use not regexp_like(...
Putting all this together I think you need:
AND NOT REGEXP_LIKE (A.SRVC_CALL_DN, '^TEST[[:space:]]CALL')
This excludes every match from your query where the string starts with 'TEST CALL'. However, if this string may be in any position in the column you need to remove the carat - ^.
This also assumes that the string is always in upper case. If it's in mixed case or lower, then you need to change it again. Something like the following:
AND NOT REGEXP_LIKE (upper(A.SRVC_CALL_DN), '^TEST[[:space:]]CALL')
By upper-casing SRV_CALL_DN you ensure that you're always going to match but ensure that your query may not use an index on this column. I wouldn't worry about this particular point as regular expressions queries can be fairly poor at using indexes anyway and it appears as though SRVC_CALL_ID is indexed.
Also if it may not include 'CALL' you will have to remove this. It is best when using regular expressions to make your match pattern as explicit as possible; so include 'CALL' if you can.
Try with '^TEST' or '^TEST.*'
Your regexp means any string not starting with any of the characters: T,E,S,T.
But your case is so simple, starts with TEST. Why not use a simple like:
LIKE 'TEST%'

Is it possible to ignore characters in a string when matching with a regular expression

I'd like to create a regular expression such that when I compare the a string against an array of strings, matches are returned with the regex ignoring certain characters.
Here's one example. Consider the following array of names:
{
"Andy O'Brien",
"Bob O'Brian",
"Jim OBrien",
"Larry Oberlin"
}
If a user enters "ob", I'd like the app to apply a regex predicate to the array and all of the names in the above array would match (e.g. the ' is ignored).
I know I can run the match twice, first against each name and second against each name with the ignored chars stripped from the string. I'd rather this by done by a single regex so I don't need two passes.
Is this possible? This is for an iOS app and I'm using NSPredicate.
EDIT: clarification on use
From the initial answers I realized I wasn't clear. The example above is a specific one. I need a general solution where the array of names is a large array with diverse names and the string I am matching against is entered by the user. So I can't hard code the regex like [o]'?[b].
Also, I know how to do case-insensitive searches so don't need the answer to focus on that. Just need a solution to ignore the chars I don't want to match against.
Since you have discarded all the answers showing the ways it can be done, you are left with the answer:
NO, this cannot be done. Regex does not have an option to 'ignore' characters. Your only options are to modify the regex to match them, or to do a pass on your source text to get rid of the characters you want to ignore and then match against that. (Of course, then you may have the problem of correlating your 'cleaned' text with the actual source text.)
If I understand correctly, you want a way to match the characters "ob" 1) regardless of capitalization, and 2) regardless of whether there is an apostrophe in between them. That should be easy enough.
1) Use a case-insensitivity modifier, or use a regexp that specifies that the capital and lowercase version of the letter are both acceptable: [Oo][Bb]
2) Use the ? modifier to indicate that a character may be present either one or zero times. o'?b will match both "o'b" and "ob". If you want to include other characters that may or may not be present, you can group them with the apostrophe. For example, o['-~]?b will match "ob", "o'b", "o-b", and "o~b".
So the complete answer would be [Oo]'?[Bb].
Update: The OP asked for a solution that would cause the given character to be ignored in an arbitrary search string. You can do this by inserting '? after every character of the search string. For example, if you were given the search string oleary, you'd transform it into o'?l'?e'?a'?r'?y'?. Foolproof, though probably not optimal for performance. Note that this would match "o'leary" but also "o'lea'r'y'" if that's a concern.
In this particular case, just throw the set of characters into the middle of the regex as optional. This works specifically because you have only two characters in your match string, otherwise the regex might get a bit verbose. For example, match case-insensitive against:
o[']*b
You can add more characters to that character class in the middle to ignore them. Note that the * matches any number of characters (so O'''Brien will match) - for a single instance, change to ?:
o[']?b
You can make particular characters optional with a question mark, which means that it will match whether they're there or not, e.g:
/o\'?b/
Would match all of the above, add .+ to either side to match all other characters, and a space to denote the start of the surname:
/.+? o\'?b.+/
And use the case-insensitivity modifier to make it match regardless of capitalisation.