Simple select issue with -(dash) in where clause - mysql

I need to search for a value like 1234-abc. The database doesn't have this particular value, but has another value 1234. Now the problem is when I write my query like
SELECT * FROM words WHERE tval='1234-abc'
instead of fetching an empty recordset, it fetches the 1234 value, it seems to ignore anything after the -, any idea what's going on?
http://sqlfiddle.com/#!2/9de62/3

You can use the BINARY keyword for the exact match
SELECT tval FROM words WHERE BINARY tval='1223-abc';
Binary is a built-in keyword that after your WHERE clause that forces a comparison for an exact case-sensitive match
Fiddle

The existing expression is implicitly converting the string expression to a number - you need to explicitly convert the number to a character strng, like so:
SELECT tval FROM words WHERE convert(tval,char(20))='1223-1ABCDE';
SQLFiddle here.

Related

why mysql where provide result with alphanumeric value?

When I filter numeric id with where condition inside with key all then result is like this which is correct https://prnt.sc/1ubkviy
But when we pass alpha numeric value inside where condition, still it is giving result then can you explain us in detail why this is happening https://prnt.sc/1ubkzbq
Try using BINARY for exact match:
SELECT * FROM office_category WHERE BINARY id="2sssss"

regexp mysql group

I try get name of city's from string '{"travelzoo_hotel_name":"Graduate Minneapolis","travelzoo_hotel_id":"223","city":"Minneapolis","country":"USA","sales_manager":"Stephen Conti"}'
I try this regexp:
SELECT REGEXP_SUBSTR('{\"travelzoo_hotel_name\":\"Graduate Minneapolis\",\"travelzoo_hotel_id\":\"223\",\"city\":\"Minneapolis\",\"country\":\"USA\",\"sales_manager\":\"Stephen Conti\"}'
,'(?:.city...)([[:alnum:]]+)');
I have: '"city":"Minneapolis'
Me need only name of city:Minneapolis.
How to use groups in queries?
My example in regex101
Help me Please
I assume you are using MySQL 8.x that uses ICU regex expressions.
It looks like the string you want to process is JSON. You may use JSON_EXTRACT with JSON_UNQUOTE and a '$.city' as JSON path then:
JSON_UNQUOTE(JSON_EXTRACT('{"travelzoo_hotel_name":"Graduate Minneapolis","travelzoo_hotel_id":"223","city":"Minneapolis","country":"USA","sales_manager":"Stephen Conti"}', '$.city'))
will return Minneapolis.
In your regex, the non-capturing group pattern is still matched and appended to the match value. "Non-capturing" only means no separate memory buffer is alotted to the text captured with a grouping construct. So, you may fix it with '(?<="city":")[^"]+' pattern where (?<="city":") is a positive lookbehind that matches "city":" but does not put it into the match value. The only text you will have in the output is the one matched with [^"]+, 1+ chars other than ".

mysql how to detect if column has no integer

Hi I have been trying to select the records whose column has no integer I have this piece of code and tried it different ways but still get back rows with P992142
P992142
P301716
P301716
P307162
P306522
which I don't want
select practitioner_id
from claimsprofinload
WHERE practitioner_id not like '%[0-9]%';
You're using a regular expression in conjunction with LIKE, which is not valid. What you want is the REGEXP or RLIKE comparison.
Since that expression is evaluated as a more literal string, and since none of your rows have [0-9] literally in them, it matches all rows.

Using REGEX to alter field data in a mysql query

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.

Is there any way to modify a column before it is ordered in MySQL?

I have a table with a field value which is a varchar(255). The contents of the field can be quite varied:
$1.20
$2994
$56 + tax (This one can be ignored or truncated to $56 if necessary)
I have a query constructed:
SELECT value FROM unnamed_table ORDER BY value
However, this of course uses ASCII string comparison to order the results and does not use any numerical type of comparison.
Is there a way to truly order by value without changing the field type to DECIMAL or something else? In other words, can the value field be modified ('$' removed, value converted to decimal) on the fly before the results are sorted?
You could sort on an expression made to "parse" the text into decimal
SELECT value FROM unnamed_table ORDER BY expression_returning_decimal(value)
Where your expression uses MySQL functions to extract the number from the string depending on what form you expect it to take (something like CAST(value AS DECIMAL(10,2)), but you'll probably need to deal with the extraneous non-numeric characters somehow as I'm not sure what the CAST will give if you don't strip them).
Create a second column without the $-sign, sort on that one and use the data of the original column in your application.
In order to create the helper column and sort on it you would need something like this:
SELECT value, CAST(SUBSTR(value, 2) AS UNSIGNED) sort_col
FROM unnamed_table ORDER BY sort_col