How to make exact comparision in mysql? - mysql

Consider following query
SELECT
('foo' + 1 - 1) = 'foo',
('foo' + 1 - 1),
'foo'
to my surprise it returns 1, 0, 'foo'
so how 0 equals foo?
and how to make statement that ('foo' + 1 - 1) = 'foo' will return false (0) ?

The answer is described in Type Conversion in Expression Evaluation section of the mysql documentation.
('foo' + 1 - 1) expression is evaluated as number because of the numbers and type of operators in the expression. In this context the string 'foo' is interpreted as 0. So, the above expression translates as 0+1-1 => 0. Then, this number is compared with the string 'foo'. Since one of the operands is an integer, the other is a string, the comparison is done as floating point numbers. In this context the string 'foo' is converted to 0. 0 = 0 is true, so you get 1 as a result.

I just found one solution
SELECT
binary ('foo' + 1 - 1) = binary 'foo',
('foo' + 1 - 1),
'foo'

Related

How I can get limit_exceded value if value is less than or greater than in "limit_exceded" column i would get 1 else 0 in mysql

database table_img for better understanding
Pardon me for weak English writing
my sql query that i am getting value,low_value,high_value and limit_exceded_. issue is in limit_exceded to not get correct values, it shows all 0.
SELECT `myvalues`.`value`, `sub_types`.`low_value`, `sub_types`.`high_value`,
(case when myvalues.value > sub_types.low_value and myvalues.value < sub_types.high_value then 1 else 0 end) as limit_exceded
FROM `myvalues`
JOIN `sub_types` ON `myvalues`.`sub_type_id` = `sub_types`.`id`
WHERE `myvalues`.`sub_type_id` IN('68')
AND `myvalues`.`observation_id` IN('455', '471', '470', '469', '468', '467', '466', '465', '462', '461', '460', '459', '458', '457', '456', '372', '453', '373', '376', '439', '440', '441', '442', '443', '445', '446', '447', '448', '452', '454')
I want to get int 1 in front of those values whose value is less than 40 or greater than 180. Also it would it be appreciated if extract max and min from this list and count limit_exceded values
expected result is set value 1 where values is 900,9 and 1 etc
issue is in limit_exceded to not get correct values, it shows all 0
I suspect the issue is the types. The way the data lines up in the image and the use of strings in the WHERE clause suggest that the values are strings not numbers. A simply way to convert is to use + 0:
SELECT v.value, st.low_value, st.high_value,
(v.value + 0) > (st.low_value + 0) and (v.value + 0) < (st.high_value + 0) as limit_exceded
FROM myvalues v JOIN
sub_types st
ON v.sub_type_id = st.id
WHERE v.sub_type_id IN ('68') AND
v.observation_id IN ('455', '471', '470', '469', '468', '467', '466', '465', '462', '461', '460', '459', '458', '457', '456', '372', '453', '373', '376', '439', '440', '441', '442', '443', '445', '446', '447', '448', '452', '454')
Notes:
Table aliases make the query easier to write and to read.
Unnecessary backticks just make the query harder to write and to read.
In MySQL, you don't need the CASE expression -- you can just use the boolean expression.
That said, you should fix the data, not the query. If the values are numbers, store them as numbers, not string.

Regexp Mysql test if odd characters match

I have strings that are 6 characters in length and I need to test if the first character and third are the same, or the 1st and 5th or 3rd and 5th. The strings contain letters and numbers
So
aabbcc --> false
abbcad --> true
aaabcd --> true
bacada --> false
1a1b33 --> true
I need this to be part of a mysql query. Help is greatly appreciated!
The simplest (and probably fastest) way is to compare the individual substrings:
SELECT str,
SUBSTR(str, 1, 1) = SUBSTR(str, 3, 1) OR
SUBSTR(str, 1, 1) = SUBSTR(str, 5, 1) OR
SUBSTR(str, 3, 1) = SUBSTR(str, 5, 1) AS matching
FROM data
Output
str matching
aabbcc 0
abbcad 1
aaabcd 1
bacada 0
1a1b33 1
If you are running MySQL 8+ you can take advantage of the enhanced regex capability to use back-references in the pattern:
SELECT str,
REGEXP_LIKE(str, '^(.).\\1') OR
REGEXP_LIKE(str, '^(.)...\\1') OR
REGEXP_LIKE(str, '^..(.).\\1') AS matching
FROM data
Output is the same as the previous query:
str matching
aabbcc 0
abbcad 1
aaabcd 1
bacada 0
1a1b33 1
Demo on dbfiddle
You can use substring().
...
WHERE substring(nmuloc, 1, 1) = substring(nmuloc, 3, 1)
OR substring(nmuloc, 1, 1) = substring(nmuloc, 5, 1)
OR substring(nmuloc, 3, 1) = substring(nmuloc, 5, 1)
...

MYSQL REGEX in Select query

Need a Regex solution to select only a pattern of string from a column.
Data looks like this:
Column1
Data Type = String
Data =
"130 - 66||109,118 - 3||102 - 18||109,118 - 2||109,116,149 - 14||141 - 8||130 - 31||102 - 12"
Expected Result
66, 3, 18, 2, 14, 8, 31, 12
Tried REgex - "\-(...*?)\W" but it doesn't work.
You can try this
SELECT REPLACE(REGEXP_REPLACE('130 - 66||109,118 - 3||102 - 18||109,118 - 2||109,116,149 - 14||141 - 8||130 - 31||102 - 12',
'(([,0-9]+) - )', ''),'||',',');
and result
66,3,18,2,14,8,31,12
Referance
MySQL REGEXP returns a boolean, not a string.
excerpt from MySQL Reference Manual:
Returns 1 if the string expr matches the regular expression specified by the pattern pat, 0 otherwise. If expr or pat is NULL, the return value is NULL.
Maybe we want to use MySQL REGEXP_REPLACE function ?
Reference:
https://dev.mysql.com/doc/refman/8.0/en/regexp.html#operator_regexp
https://dev.mysql.com/doc/refman/8.0/en/regexp.html#function_regexp-replace

Mask integer field in mysql

I need to mask integer field in mysql such that 9999911111 becomes 9900001111. I want to keep first 2 digits and last 4 digits and need to mark rest of the digits as 0 for the integers stored in the field.
I have created a query and it's working but I am not sure whether this is right way to do for integers or not.
update table_name
set field_name=CONCAT(SUBSTR(field_name, 1, 2),
REPEAT('0', CHAR_LENGTH(field_name) - 6),
SUBSTR(field_name, CHAR_LENGTH(field_name)-3, CHAR_LENGTH(field_name)));
Just trying a different approach .
SET #myVar = 344553543534;
SELECT #myVar - (SUBSTRING(#myVar, 4, LENGTH(#myVar) - 7) * 10000) ;
Above mentioned formula will give 344000003534 as the result. Tried with different combination and found it working.
So your query need to change as given below
UPDATE table_name
SET field_name=
(field_name - (SUBSTRING(field_name, 4, LENGTH(field_name) - 7) * 10000));
Explanation :
Consider Number, a = 344553543534;
Expected Result, b = 344000003534;
c = (a - b) = 344553543534 - 344000003534 = 553540000;
Now if you consider the result, c, 55354 is the numbers where masking required, and 0000 indicates the last 4 number to be left open.
So to get masked value, we can use the formula, b = a - c;
So now to get c, used SUBSTRING(a, 4, LENGTH(a) - 7) * 10000
EDIT : To keep only first two numbers, use 3 instead of 4 and 6 instead of 7. I assumed that you needed to keep first 3.
SET #myVar = 344553543534;
SELECT #myVar - (SUBSTRING(#myVar, 3, LENGTH(#myVar) - 6) * 10000) ;

how to update flag bit in mysql query?

This is my sql query,In flag(00000) every bit position have different specification, e.g. change 4th bit position to 1 when user is inactive.Here flag is varchar datatype(String).
$sql="select flag from user where id =1"
I got
flag=10001 #it may be flag="00001" or flag="00101"
I want to update 2nd bit of this flag to 1.
$sql="update user set flag='-1---' where id=1" #it may be flag='11001' or flag='01001' or flag='01110'
Actually,I want to to update 2nd bit of this flag to 1,but with out updating it like flag='11001'.I want to do some thing like this.
$sql="update user set flag='--change(flag,2bit,to1)--' where id =1" #this is wrong
What can I do for it , only using one sql query?Is it possible?
update user
set flag = lpad(conv((conv(flag, 2, 10) | 1 << 3), 10, 2), 5, '0')
where id = 1
conv(flag, 2, 10) converts the flag string from binary to decimal.
1 << 3 shifts a 1 bit 3 binary places to the left
| performs a binary OR of this, to set that bit. This arithmetic operation will automatically coerce the decimal string to a number; you can use an explicit CAST if you prefer.
conv(..., 10, 2) will convert the decimal string back to a binary string
lpad(..., 5, '0') adds leading zeroes to make the string 5 characters long
FIDDLE DEMO
To set the bit to 0, you use:
set flag = lpad(conv((conv(flag, 2, 10) & ~(1 << 3)), 10, 2), 5, '0')
you want to use the bitwise or operator |
update user set flag = flag | (1 << 1) where id =1
if flag was 101 flag will now be 111
if flag was 000 flag will now be 010
1 << 1 shifts 1 up one bit - making it 10 (binary 2)
edit - not tested but use
update user set flag = cast(cast(flag AS SIGNED) | (1 << 1) AS CHAR) where id =1
If you are going to use a VARCHAR, you are better off using string manipulation functions: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html
UPDATE user
SET flag = CONCAT(LEFT(flag, 1), '1', RIGHT(flag, 3))
WHERE id = 1
However, you probably want to convert this field to an INT so that you can use the bit functions: http://dev.mysql.com/doc/refman/5.0/en/bit-functions.html