MYSQL REGEX in Select query - mysql

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

Related

BIT_COUNT(hash1^hash2) interprets the result of hash1^hash2 as a string

So:
b'1010' ^ b'0000' = 1010
if I do:
BIT_COUNT(b'1010' ^ b'0000') I get the right result (2)
But if I select the same values from the table (binary fields)
BIT_COUNT(hash1 ^ hash2) I get the wrong result
Even if I make the fields hexadecimal in the table and try to cast them to binary and then count the bits, I still get the same wrong result:
BIT_COUNT(CONV(hex_hash1, 16, 2) ^ CONV(hex_hash2, 16, 2))
Another example of weird behaviour, if I do the following query:
SELECT
BIT_COUNT(CONV('b', 16, 2) ^ CONV('d', 16, 2))
I get 9 as a result, when it should've been 2. From what I can see the result is processed as a string, I tried CAST(), CONV() and so on, and none of it works.
Anyone knows why?
(here is my environment)
'innodb_version', '5.7.23'
'protocol_version', '10'
'slave_type_conversions', ''
'tls_version', 'TLSv1,TLSv1.1,TLSv1.2'
'version', '5.7.23-log'
'version_comment', 'Source distribution'
'version_compile_machine', 'x86_64'
'version_compile_os', 'Linux'

How to make exact comparision in 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'

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

Split column string into multiple columns strings

I have a entry in the table that is a string which is delimited by semicolons. Is possible to split the string into separate columns? I've been looking online and at stackoverflow and I couldn't find one that would do the splitting into columns.
The entry in the table looks something like this (anything in brackets [] is not actually in my table. Just there to make things clearer):
sysinfo [column]
miscInfo ; vendor: aaa ; bootr: bbb; revision: ccc; model: ddd [string a]
miscInfo ; vendor: aaa ; bootr: bbb; revision: ccc; model: ddd [string b]
...
There are a little over one million entries with the string that looks like this. Is it possible in mySQL so that the query returns the following
miscInfo, Vendor, Bootr, Revision , Model [columns]
miscInfo_a, vendor_a, bootr_a, revision_a, model_a
miscInfo_b, vendor_b, bootr_b, revision_b, model_b
...
for all of the rows in the table, where the comma indicates a new column?
Edit:
Here's some input and output as Bohemian requested.
sysinfo [column]
Modem <<HW_REV: 04; VENDOR: Arris ; BOOTR: 6.xx; SW_REV: 5.2.xxC; MODEL: TM602G>>
<<HW_REV: 1; VENDOR: Motorola ; BOOTR: 216; SW_REV: 2.4.1.5; MODEL: SB5101>>
Thomson DOCSIS Cable Modem <<HW_REV: 4.0; VENDOR: Thomson; BOOTR: 2.1.6d; SW_REV: ST52.01.02; MODEL: DCM425>>
Some can be longer entries but they all have similar format. Here is what I would like the output to be:
miscInfo, vendor, bootr, revision, model [columns]
04, Arris, 6.xx, 5.2.xxC, TM602G
1, Motorola, 216, 2.4.1.5, SB5101
4.0, Thomson, 2.1.6d, ST52.01.02, DCM425
You could make use of String functions (particularly substr) in mysql: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html
Please take a look at how I've split my coordinates column into 2 lat/lng columns:
UPDATE shops_locations L
LEFT JOIN shops_locations L2 ON L2.id = L.id
SET L.coord_lat = SUBSTRING(L2.coordinates, 1, LOCATE('|', L2.coordinates) - 1),
L.coord_lng = SUBSTRING(L2.coordinates, LOCATE('|', L2.coordinates) + 1)
In overall I followed UPDATE JOIN advice from here MySQL - UPDATE query based on SELECT Query and STR_SPLIT question here Split value from one field to two
Yes I'm just splitting into 2, and SUBSTRING might not work well for you, but anyway, hope this helps :)