Mysql replace not all string? - mysql

I have column(pro_doc) string like [1,2,11,]
UPDATE product SET prod_doc = REPLACE(prod_doc, '1,' , '') WHERE prod_id = 2
The result is 2,1
I want become 2,11,
I just want replace first 1, not all 1,
Have any solution?
Thanks a lot...

Use SUBSTRING_INDEX.
Find the total occurence of , and use negative of that as the last argument of the SUBSTRING_INDEX function.
UPDATE product
SET prod_doc =
SUBSTRING_INDEX(
prod_doc, ',', -(
ROUND(
(
LENGTH(prod_doc) - LENGTH(REPLACE(prod_doc, ',', ''))
) / LENGTH(','))
)
)
WHERE prod_id = 2;
SQL Fiddle Demo

Related

MySQL query error "Subquery returns more than 1 row" where update into the same table

How to update to the same table? i tried to do fraction conversion and update 1 of the rows in the same table but the error "Subquery returns more than 1 row"
Below are the code, (State1 is the table itself, Share field consists of those fraction data like 1/2,1/5 ..)
UPDATE State1 set shareresult =(SELECT
x.Multiplier / x.Divider as Result
from
(select
cast( substr( t.share,
1,
locate('/', t.share) - 1)
as decimal)
as Multiplier,
cast( substr( t.Share,
locate('/', t.Share) + 1,
locate( ' ',
concat(t.Share, ' ')))
as decimal)
as Divider
from
State1 t ) x)
thanks
Finally, i managed to solve my problem with the code below
CREATE TEMPORARY TABLE activity_product_ids AS SELECT x.NumberID, x.Multiplier / x.Divider as Result from (select cast( substr( t.share, 1, locate('/', t.share) - 1) as decimal) as Multiplier, cast( substr( t.Share, locate('/', t.Share) + 1, locate( ' ', concat(t.Share, ' '))) as decimal) as Divider, t.ID as numberID from State1 t) x;
UPDATE State1 a
JOIN activity_product_ids b
ON a.ID=b.NumberID
SET a.shareresult=b.Result;
Thanks for all the replies.
Neither your update statement nor the sub-query has a WHERE clause so it looks like you are trying to update every row with fraction to decimal conversion of every row.
This is a much simpler approach -
UPDATE State1
SET shareresult = ROUND(SUBSTRING_INDEX(share, '/', 1) / SUBSTRING_INDEX(share, '/', -1), 2)
WHERE id = 1;

Sort MySQL results by a column with several values separated by a period

I suspect this may have already been asked, but I'm not sure how to phrase the question so that SO search engine picks it up.
I have a column called TCID, which contains values in this format:
1.A.1.1.1
4.A.1.1.1
2.B.1.1.10
2.B.1.1.2
...
There are 5 units in this TCID, separated by periods. I want the position to the left to take the highest priority, and then finally the last digit is the lowest priority.
So it would sort like this:
1.A.1.1.1
2.B.1.1.2
2.B.1.1.10
4.A.1.1.1
Here is the query I have so far. It almost works, but the last position is not getting sorted.
SELECT *
FROM system
WHERE cluster = \"$tc_name\"
ORDER BY CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',1) , 1 ) AS UNSIGNED),
SUBSTR( SUBSTRING_INDEX(tcid,'.',2) , LENGTH( SUBSTRING_INDEX(tcid,'.',1)) + 2 ),
CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',3) , LENGTH( SUBSTRING_INDEX(tcid,'.',2)) + 2 ) AS UNSIGNED),
CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',4) , LENGTH( SUBSTRING_INDEX(tcid,'.',3)) + 2 ) AS UNSIGNED)
Can anyone help me fix this or suggest a better way to do this?
There are obviously better ways to store this information in the database, such as storing the values in separate fields. However, it's not always possible to change the code base to do such things.
But I believe you just need to add the final order by to your query in order to for it to work as expected;
SELECT *
FROM system
WHERE cluster = "<some search term>"
ORDER BY CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',1) , 1 ) AS UNSIGNED),
SUBSTR( SUBSTRING_INDEX(tcid,'.',2) , LENGTH( SUBSTRING_INDEX(tcid,'.',1)) + 2 ),
CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',3) , LENGTH( SUBSTRING_INDEX(tcid,'.',2)) + 2 ) AS UNSIGNED),
CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',4) , LENGTH( SUBSTRING_INDEX(tcid,'.',3)) + 2 ) AS UNSIGNED),
CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',5) , LENGTH( SUBSTRING_INDEX(tcid,'.',4)) + 2 ) AS UNSIGNED);
Please see this sqlfiddle to check
Just for fun...
SELECT *
FROM
(
SELECT '1.A.1.1.1' x
UNION ALL
SELECT '4.A.1.1.1'
UNION ALL
SELECT '2.B.1.1.10'
UNION ALL
SELECT '2.B.1.1.2'
) a
ORDER BY
INET_ATON(CONCAT(MID(x,1,1),MID(x,4,1000)));

mySQL extract number or string depending on value

Please take a look at a table below:
I need "the last part" of "what I have" to be number if it's all number and string if it contains character.
In Excel I've achieved this with the following function (as shown above):
=IFERROR(VALUE(TEXT(D2;"0"));TEXT(D2;"0"))
However I want to do this in mySQL in order to compute more effectively.
I've "floated" somwhere around CASE with CAST or CONVERT and also TRIM functions, but I haven't been able to put up something sensical.
A nice "bonus" would be to extract "the part part" by looking for the last "" character (so first "" from right of the string) but no idea at all how to achieve that.
Use SUBSTRING_INDEX.
Query
SELECT
CASE
WHEN SUBSTRING_INDEX(records.data, '_', -1) > 1 # is int check '00004949' returns 1
THEN SUBSTRING_INDEX(records.data, '_', -1) + 0 # converts '00004949' to 4949
ELSE SUBSTRING_INDEX(records.data, '_', -1)
END
AS word
FROM (
SELECT "TRA_PL_NWL_EMA_NWLY_DAI_000_20170610_IN1_01P002bc" AS DATA
UNION
SELECT "TRA_PL_NWL_EMA_NWLY_DAI_000_2017_0909_JET_00004949" AS DATA
) records
Result
word
----------
01P002bc
4949
Following query will somewhat achieve the task:
SELECT
case
when SUBSTRING_INDEX(value, "_", -1) REGEXP('(^[0-9]+$)')
then Trim(Leading 0 from SUBSTRING_INDEX(value, "_", -1))
else SUBSTRING_INDEX(value, "_", -1)
end as Value
From yourtable;
Click here for Demo
Hope it helps!
I hope this is what u want.
At least it does what you have asked for.
SELECT
CASE
WHEN (
CONVERT(
substring(
txt,
LENGTH(txt) - LOCATE('_', REVERSE(txt))+2,
length(txt)
)
, signed integer
)
) = 0
THEN substring(
txt,
LENGTH(txt) - LOCATE('_', REVERSE(txt))+2,
length(txt)
)
ELSE CONVERT(
substring(
txt,
LENGTH(txt) - LOCATE('_', REVERSE(txt))+2,
length(txt)
)
, signed integer
)
END as NUMBER
from test.test
This is my test Table and result of SQL:
txt NUMBER
DA_DA_ADAD_ADAD_ADAD_asd123 asd123
DA_DA_ADAD_ADAD_ADAD_000123 123
DA_DA_ADAD_ADAD_ADAD_444 444
DA_DA_ADAD_ADAD_ADAD_bsd123 bsd123
DA_DA_ADAD_ADAD_ADAD_csd123 csd123
DA_DA_ADAD_ADAD_ADAD_dsd123 dsd123

How to select string between characters?

I made this table:
Table (Websites)
WebsiteID | WebsiteName
2324442 'http://www.samsung.com/us/'
2342343 'https://www.microsoft.com/en-au/windows/'
3242343 'http://www.apple.com/au/iphone/'
And I want to be able to SELECT the domain names from this table.
Something like this:
WebsiteName
'www.samsung.com'
'www.microsoft.com'
'www.apple.com'
Is there a string method I can use for this? Like splitting the string between // and /.
You can use SUBSTRING_INDEX() :
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(websiteName, '//', -1),
'/', 1)
FROM table
You can even use the following:
SELECT WebsiteID , WebsiteName
(CHARINDEX ( '//', WebsiteName, 1 ) + 1), -- Position of the double slashes
CHARINDEX( '/', REVERSE (WebsiteName ), 1), -- Position of the last single slash
SUBSTRING(WebsiteName, (CHARINDEX ( '//' , WebsiteName, 1 ) + 2), CHARINDEX( '/', REVERSE (WebsiteName ), 1) ) -- Final string
FROM Table

MySQL Variable Substitution

I want to simplify the following using dynamic SQL like one could do in Transact SQL.
I want to do something like:
SET #s = replace(field_name, '_complete','')
and use #s instead of replace(field_name, '_complete','')
Please adive if possible and if so how.
My current code:
select distinct
if(instr(replace(field_name, '_complete',''),'_') <= 5
,left(replace(field_name, '_complete','')
,instr(replace(field_name, '_complete',''),'_') - 1
)
,replace(field_name, '_complete','')
) AS form_id ,replace(
if(instr(replace(field_name, '_complete',''),'_') <= 5,
mid(replace(field_name, '_complete',''),
instr(replace(field_name, '_complete',''),'_') + 1,
length(replace(field_name, '_complete','')) - instr(replace(field_name, '_complete',''),'_')
)
,replace(field_name, '_complete','')
),
'_',
' ') as form_name ,field_name from redcap_extract2use where field_name like '%_complete' order by 1;
The above would then be replaced with:
select distinct
if(instr(#s,'_') <= 5 ,left(#s,instr(#s,'_') - 1),#s ) AS form_id
,replace( if(instr(#s,'_') <= 5,
mid(#s,instr(#s,'_') + 1,length(#s) - instr(#s,'_')),#s), '_', ' ') as form_name
,field_name
from redcap_extract2use
where field_name like '%_complete'
order by 1;
and I would have an execute... to run the query
If I'm understanding your question correctly then you would want to use the PREPARE and the EXECUTE statements.
For example:
SET #s = replace(field_name, '_complete','');
PREPARE mystatement FROM
SELECT DISTINCT ...... ;
EXECUTE mystatement;