Mask values on mysql database - mysql

I have a column with values like this:
01709100011
I need to transform it to:
017.091.0001-1
The values have always the same characters number.
Both columns are varchar
Thanks in advance for any help.

SELECT CONCAT(SUBSTRING(test, 1,3),'.',SUBSTRING(test,4,3),'.',SUBSTRING(test,7,4),'-',SUBSTRING(test,11,1)) FROM test;
In the above example I used the table test and values in column test.

SELECT CONCAT_WS( "-", CONCAT_WS( ".", SUBSTRING( foo, 0, 3 ), SUBSTRING( foo, 3, 3 ), SUBSTRING( 6, 4 )), SUBSTRING( foo, 10 , 1 )) FROM bar WHERE 1=1;

Related

Exact strings in a column in SQL

I am trying to use mysql to solve the question below.
Any idea how should I make it work? Thank you.
Tried to use the code below but extracted duplicate strings in two columns and it's hard-code so it's not working..
SELECT itemid, SUBSTRING_INDEX(SUBSTRING_INDEX(item_variation, ',', 1), ',', -1) 'type one',
SUBSTRING_INDEX(SUBSTRING_INDEX(item_variation, ',', 2), ',', -1) 'type two',
SUBSTRING_INDEX(SUBSTRING_INDEX(item_variation, ',', 3), ',', -1) 'type three',
SUBSTRING_INDEX(SUBSTRING_INDEX(item_variation, ',', 4), ',', -1) 'type four'
FROM data
Question:
To extract items with more than 3 types
|itemid|shopid|item_name|item_type|price|stock|creation_date|
|1|10000|clothes|{}|5|100|27/1/2018|
|2|10000|dress|{Pink: 20, Black: 20, Grey: 20}|20|100|20/2/2018|
|3|10001|t-shirt|{S: 2, M: 2, L: 2, XL: 2}|2|50|1/1/2018|
|4|10002|socks|{us5.5: 1, us9: 1, us4.5: 1, us10: 1, us7: 1, us6: 1, us5: 1}|1|1000|4/1/2018|
|5|10002|Gloves|{S: 2, M: 2}|2|500|6/1/2018|
Expected result
|itemid |item_name |item_type|
|3 |t-shirt |{S: 2, M: 2, L: 2, XL: 2}|
|4 |socks |{us5.5: 1, us9: 1, us4.5: 1, us10: 1, us7: 1, us6: 1, us5: 1}|
This ought to do:
select itemid, item_name, item_type
from t
where length(item_type) - length(replace(item_type, ',', '')) >= 3;
You need a special case to tell 0 and 1 apart. It would not work if item_type contains ',' in either key or value of the json-like field (missing quoted around strings to be json).
You just need to count number of comma(,)>=3. Try below code:
SELECT
Itemid,Item_Name,Item_type
FROM myjson
where ROUND (
(
LENGTH(item_type)
- LENGTH( REPLACE ( item_type, ",", "") )
) / LENGTH(",")
)>=3

MySQL JSON: finding value of sibling element in sub-array

I have the following (pseudo)JSON in a type JSON (LONGTEXT) column in my MariaDB 10.2
{"order":
{"otherstuff":...},
{"dates":
[
{
"typeId":2,
"date":"2019-05-21 09:00:00"
},
{
"typeId":4,
"date":"2019-05-21 10:00:00"
}
]
}
}
What I need is the order's date while I know which type I need (4).
An order can have a number of dates identified by their typeId. typeId 4 is not always in second position.
SELECT JSON_UNQUOTE(JSON_SEARCH(`json`, 'one', 4, NULL, '$.dates[*].typeId'))
// gives me: $.dates[1].typeId
My first thought now was to REPLACE typeId with date, but that complains about mixed collations.
How would I (more elegantly) reference the 'date' value here?
Also, the query is supposed to be the expression of a GENERATED column in my table. Since date id4 is not necessarily there for every order, I tried this:
SELECT IF(4 IN (JSON_EXTRACT(json, '$.dates[*].typeId')), 'yes', 'no')
// above condition evaluates to [2, 4]
I have trimmed away '[' and ']' but then it only gives me a 'yes' if 4 is first in the array (is it an array?).
So (without brackets):
[4, 7] -> yes
[2, 4] -> no
I'm assuming this doesn't get recognized as an array of values but a string. Then why does it give me 'yes' if my needle is in first position?
Instead of yes and no I obviously want to use the date and NULL.
The MySQL JSON functions are quite new to me. So maybe someone could point me in the right direction?
Try:
Option 1:
SELECT
JSON_UNQUOTE(
JSON_EXTRACT(
`json`,
REPLACE(
JSON_UNQUOTE(
JSON_SEARCH(
`json`,
'one',
4,
NULL,
'$.order.dates[*].typeId'
)
),
'typeId',
'date'
)
)
) `date`;
Option 2:
SELECT
IF(
JSON_CONTAINS(
JSON_EXTRACT(
`json`,
'$.order.dates[*].typeId'
),
4
),
'yes',
'no'
) `exists`;
See dbfiddle.

oracle11g regexp_replace for json

I have select:
select regexp_replace(regexp_substr('[{"date": "01_2016", "val":"100_22"},{"date": "02_2016","val": "200.10"}]'
,'"val":\s*("(\w| )*")', 1, level)
,'"val":\s*"((\w| )*)"', '\1', 1, 1) val
from dual
connect by regexp_substr('[{"date": "01_2016", "val":"100_22"},{"date": "02_2016","val": "200.10"}]', '"val":\s*("(\w| )*")', 1, level) is not null
;
If my value have format 100_10 it is ok. But I want 100.10 and this select not support this. How to write regexp_replace?
Use (\d+)_(\d+) to match only the numeric values separated by an underscore:
SELECT REGEXP_REPLACE(
'[{"date": "01_2016", "val":"100_22"},{"date": "02_2016","val": "200.10"}]',
'"val":"(\d+)_(\d+)"',
'"val":"\1.\2"'
)
FROM DUAL;
Thanks everybody. I found the solution
select regexp_replace(regexp_substr('[{"date": "01-2016", "val":"100.22"},{"date": "02-2016","val": "200.10"},{"date": "03-2016","val": "200.15"}]','"val":\s*("(\w|[..])*")', 1, level),'"val":\s*"((\w|[..])*)"', '\1', 1, 1) val, regexp_replace(regexp_substr('[{"date": "01-2016", "val":"100.22"},{"date": "02-2016","val": "200.10"},{"date": "03-2016","val": "200.15"}]' ,'"date":\s*("(\w|[-])*")', 1, level) ,'"date":\s*"((\w|[-])*)"', '\1', 1, 1) date_period from dual connect by regexp_substr('[{"date": "01-2016", "val":"100.22"},{"date": "02-2016","val": "200.10"},{"date": "03-2016","val": "200.15"}]', '"val":\s*("(\w|[..])*")', 1, level) is not null

Convert to date format from integer

I have date in integer format 140529(yymmdd). I want this date to be date format to be as 2014-05-29.
How can i do this . Please Help
Try:
SELECT CONCAT('20', SUBSTR ( 150817 , 0, 2 ), '-', SUBSTR ( 150817 , 3, 2 ), '-', SUBSTR ( 150817 , 5, 2 )) AS DATE;
And replace the "integer date" 150817 with your date

replace() concat() and substr() add character at specific location in string cannot get the position right

End result: all 3 fields should be merged (solved OK), and the character "T" should be added as the 5th character in the merged string (no other characters should be removed or altered in sequence). (see all specifics below).
What am I doing wrong?
Data is in the following format:
data1: AL
data2: 33 0230S 0440E
data3: SW
Here is my current sql:
replace(concat(b.data1,
substr(b.data2, 4, 1),
'T',
substr(b.data2, 1),
b.data3), ' ', '')
AS MergedData
The final output should look like:
AL33T0230S0440ESW
I've been able to get the "T" placed at random locations, but cannot get it consistently added as the 5th character from the start of the string.
Use:
replace only on data2 (because that's the only field that needs it), then
concat() to join it all up, and finally
the insert() function to insert the T
(Don't use substr at all)
insert(concat(data1, replace(data2, ' ', ''), data3), 5, 0, 'T')
Here's a test:
set #data1 := 'AL', #data2 := '33 0230S 0440E', #data3 := 'SW';
select
insert(concat(#data1, replace(#data2, ' ', ''), #data3), 5, 0, 'T')
as MergedData;
Output:
+-------------------+
| MergedData |
+-------------------+
| AL33T0230S0440ESW |
+-------------------+
Random locations seems odd, this seems to work though;
replace(concat(b.data1,
substr(b.data2, 1, 2),
'T',
substr(b.data2, 4),
b.data3), ' ', '')
Demo here.
Find the position of the first space in data2, replace it with T, remove the rest of the spaces in the resulting string, then concatenate it with the two other values:
CONCAT(
b.data1,
REPLACE(INSERT(b.data2, LOCATE(' ', b.data2), 1, 'T'), ' ', ''),
b.data3
) AS MergedData