First let me apologize I have not been successful in finding anything online with this specific scenario.
I have been using MySQL for quite some time, but I am hoping to get some clarification on a certain situation I have come across, which honestly bothers me quite a bit.
I'm trying to match a string in a MySQL column that contains both \ and % literal characters using the LIKE operator.
Inside the table I have two records:
id value
-----------------------
1 100\\%A
2 100\%A
They both contain literal special characters.
If I do a SELECT, in an attempt to only match the first record (id=1), I would expect to write the query as such:
SELECT * FROM table_name WHERE value LIKE '%0\\\\\%A'
(\\\\ to match two literal backslashes, plus a backslash before % to match a literal %)
However, It only matches the row (id=2), which makes no sense to me.
If I change the query a little to be:
SELECT * FROM table_name WHERE value LIKE '%0\\\\%A'
I would expect to match the id=1 row only, (\\\\ to match 2 literal backslashes, and the % is not literal and should represent a wildcard). But instead, it matches both rows?
row (id=2) only has a single backslash but still matches.
Is row id=2 matching because the first 2 backslashes are matching the \, the 3rd backslash is ignored for some reason, and the 4th backslash is allowing a literal match on the %?
If I do a:
SELECT * FROM table_name WHERE value LIKE '%0\\\\\\\%A'
I for some reason get row (id=1), when I would expect to get no matches whatsoever.
I'm trying to find a solution in which I can do partial matches on any series of characters accurately, including those with consecutive special characters such as the scenario above. However, I'm having an impossible time trying to plan for situations such as these.
Any input would be greatly appreciated.
Maybe this help you understand the usage of escape chars in mySQL
https://stackoverflow.com/a/27061961/634698
I have a field, "ID" that is formatted as ###""-""##. For example 545R-T67. I have another field "Name" in the same table that pulls the information before the dash and creates it into its own field.
Right now the field is calculated to pull the first four characters Left([ID],4) the Data edition requires the data to be formatted to include data with two letters after the three numbers.
I am wondering how I can update the field to pull all characters before the dash instead of just a set amount. Is there a function in Access that makes this possible?
You can combine LEFT with INSTR to do this. INSTR returns the position of the character you're looking for (the dash).
Left([ID],INSTR([ID], "-"))
Note this will return everything before the first dash, but will return a zero-length string if there's no dash at all.
I have a dictionary database in which every entery looks like this
column
word; synonym; synonym | example of usage; example of usage
I want to make a select function that will only get the row if it appears in the first part of the data (words and synonyms) and not in the examples of usage (as there are more words there)
I have been trying to do it with REGEXP
SELECT * FROM dictionary WHERE column REGEXP '[^\|]*word.*\|.*'
But for some reason this matches everything in the tables - even where the word doesn't appear at all.
What am I doing wrong?
You need to use double slashes to escape special characters in MySQL regex. Thus, your \| is treated as a | and you match every empty space before each "character" in each string.
I suggest just checking if word appears before | with
'^[^|]*word'
or - if you need a whole word check:
'^[^|]*[[:<:]]word[[:>:]]'
The regex matches...
^ - start of string
[^|]* - 0 or more characters other than |
[[:<:]] - leading word boundary
word - literal sequence of letters
[[:>:]] - trailing word boundary.
Also, this regex is case-insensitive by default. To make it case-sensitive, use BINARY keyword.
SELECT * FROM dictionary WHERE column REGEXP BINARY '^[^|]*[[:<:]]word[[:>:]]'
What am I doing wrong?
You don't have a database. You have 3 types of information (word, synonym, usage) jammed into one column in one row.
You need a table of word - synonym pairs
You need a table of word - usage pairs
You probably need a word - definition pair table
Do all the parsing before inserting the data into the tables.
I have a column containing values as strings. I need to keep only those that contain one of the following substrings: |MB1, |MB2, |MB3, |MB4, |MB5 and |MB6.
My starting point is:
select * from table
where column like '%|MB_%';
However, this would keep any other row with values such as |MBa or others. How do I get rid of them?
P.S. I am using MySQL
You can use MySQL's regular expression pattern matching;
WHERE `column` REGEXP '\\|MB[1-6]'
The pattern '\\|[1-6]' can be analysed as follows:
\\ is the string-encoding of a literal backslash, which is the regular expression escape character, so that
| is given no special meaning (if not escaped by backslash it would signify alternation, which would lead to an invalid pattern in this case)
MB are literal characters
[1-6] represents a single character within the range 1 through to 6
I have two databases, both containing phone numbers. I need to find all instances of duplicate phone numbers, but the formats of database 1 vary wildly from the format of database 2.
I'd like to strip out all non-digit characters and just compare the two 10-digit strings to determine if it's a duplicate, something like:
SELECT b.phone as barPhone, sp.phone as SPPhone FROM bars b JOIN single_platform_bars sp ON sp.phone.REGEX = b.phone.REGEX
Is such a thing even possible in a mysql query? If so, how do I go about accomplishing this?
EDIT: Looks like it is, in fact, a thing you can do! Hooray! The following query returned exactly what I needed:
SELECT b.phone, b.id, sp.phone, sp.id
FROM bars b JOIN single_platform_bars sp ON REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(b.phone,' ',''),'-',''),'(',''),')',''),'.','') = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(sp.phone,' ',''),'-',''),'(',''),')',''),'.','')
MySQL doesn't support returning the "match" of a regular expression. The MySQL REGEXP function returns a 1 or 0, depending on whether an expression matched a regular expression test or not.
You can use the REPLACE function to replace a specific character, and you can nest those. But it would be unwieldy for all "non-digit" characters. If you want to remove spaces, dashes, open and close parens e.g.
REPLACE(REPLACE(REPLACE(REPLACE(sp.phone,' ',''),'-',''),'(',''),')','')
One approach is to create user defined function to return just the digits from a string. But if you don't want to create a user defined function...
This can be done in native MySQL. This approach is a bit unwieldy, but it is workable for strings of "reasonable" length.
SELECT CONCAT(IF(SUBSTR(sp.phone,1,1) REGEXP '^[0-9]$',SUBSTR(sp.phone,1,1),'')
,IF(SUBSTR(sp.phone,2,1) REGEXP '^[0-9]$',SUBSTR(sp.phone,2,1),'')
,IF(SUBSTR(sp.phone,3,1) REGEXP '^[0-9]$',SUBSTR(sp.phone,3,1),'')
,IF(SUBSTR(sp.phone,4,1) REGEXP '^[0-9]$',SUBSTR(sp.phone,4,1),'')
,IF(SUBSTR(sp.phone,5,1) REGEXP '^[0-9]$',SUBSTR(sp.phone,5,1),'')
) AS phone_digits
FROM sp
To unpack that a bit... we extract a single character from the first position in the string, check if it's a digit, if it is a digit, we return the character, otherwise we return an empty string. We repeat this for the second, third, etc. characters in the string. We concatenate all of the returned characters and empty strings back into a single string.
Obviously, the expression above is checking only the first five characters of the string, you would need to extend this, basically adding a line for each position you want to check...
And unwieldy expressions like this can be included in a predicate (in a WHERE clause). (I've just shown it in the SELECT list for convenience.)
MySQL doesn't support such string operations natively. You will either need to use a UDF like this, or else create a stored function that iterates over a string parameter concatenating to its return value every digit that it encounters.