How to auto increment a string with sql query - mysql

I am stuck at a point where i have to increment a string, and my strings are of type C001,SC001,B001
in my data base they are defined like
what i am trying to do do is write a query which check the previous highest code present into my db and the incriment it to +1
for example C001 -> C002,C009->C010,C099`->C100 and so on
Similarly for SC001->SC002,SC009->SC010,SC099->SC100 and so on
Similarly fro B001 -> B002,B009->B010,B099`->B100 and so on
I have a query which my friend has suggested me to use but that query only incriminating AAAA->AAAA01 , AAAA09->AAAA10
query is
SELECT id AS PrevID, CONCAT(
SUBSTRING(id, 1, 4),
IF(CAST(SUBSTRING(id, 5) AS UNSIGNED) <= 9, '0', ''),
CAST(SUBSTRING(id, 5) AS UNSIGNED) + 1
) AS NextID
FROM (
-- since you allow strings such as AAAA20 and AAAA100 you can no longer use MAX
SELECT id
FROM t
ORDER BY SUBSTRING(id, 1, 4) DESC, CAST(SUBSTRING(id, 5) AS UNSIGNED) DESC
LIMIT 1
) x
when i am replacing ID with CategoryCode it is giving me PrevID-C004 NextID-C00401 which is not my requirement i want PrevID-C004 and NextID->C005
NOTE i am using my sqlServer 5.1

Just try this one ,
SELECT
CategoryCode,CAST(CONCAT(LPAD(CategoryCode,1,0),LPAD(MAX(RIGHT(CategoryCode,
3)) + 1, 3, 0) ) AS CHAR),
FROM test
SELECT
SubCategoryCode,CAST(CONCAT(LPAD(SubCategoryCode,2,0),
LPAD(MAX(RIGHT(CategoryCode, 3)) + 1, 3, 0) ) AS CHAR),
FROM test
SELECT
BrandCode,CAST(CONCAT(LPAD(BrandCode,1,0), LPAD(MAX(RIGHT(BrandCode, 3)) +
1, 3, 0)) AS CHAR) FROM test

Related

MySQL Tagging Rows in Sequence based on a pattern

I have a column which I am trying to convert in MySQL into another column with a pattern where ever there are consecutive 1s in the data. Please see the example dataset below
Dataset Sample: https://1drv.ms/x/s!ApGNZAoiMmX3gi9OR7SUxt3ou84v?e=tuSV7f
Following is the code I have written but not able to make it work and any suggestions would be helpful.
select rownum,result,movingsum,new_result
(select rownum,result,movingsum,
if(result_norm_max=0,0,if(movingsum=1,1,0)) as new_result
from
(select rownum,result,
sum(result) over (order by rownum rows between 2 preceding and current row) as movingsum
from mytable) a;
The issue is, the above code doesn't return the output needed for all required logic of:
when result column is 0 new_result should be 0
when result is 1, new_result = 1 but only when previous 2 new_results are 0
Any suggestion on how I should approach this will be useful.
Thanks!
With some tries I was able to find the solution which is close to what I need as mentioned below. I used 2 variables to carry out the trick,
select rownum,result,
if (result= 0, 0, if(#n = 1, if(#m >= 7, 1 , 0), 1)) as new_max,
if (result= 0, 0, if(#n = 1,
case when #m >= 7 then #m:=0 else 0 end
, 1)) as new_max1,
if (result= 0, if(#m>0,#m:=#m-1,#m:=0), if(#n = 1, #m:=#m+1,#m:=#m-1)) as new_m,
#n := result
from mytable a, (select #n:= 0, #m:= 0) b

Mysql : Use IF in TRUNCATE

This is the query, simplified.
SELECT `a`, TRUNCATE(`b` / 1000, 3) AS `b`
FROM (
...
) AS `m`
GROUP BY `a`
ORDER BY `a`
What i'm trying to do is change the number of decimal places (actual 3) based on the value of b.
So i tried this:
SELECT `a`, TRUNCATE(`b` / 1000, IF(`b` < 10, 2, 3)) AS `b` ...
and this
SELECT `a `, IF(`b ` < 10, TRUNCATE(`b ` / 1000, 2), TRUNCATE(`b ` / 1000, 3)) AS `b `
If b is less than 10, i want 3 decimal places, otherwise 2.
But this doesn't seem to work ...
Resources : https://dev.mysql.com/doc/refman/8.0/en/control-flow-functions.html#function_if
just change the values position that you put in your query
SELECT `a `, IF(b < 10, TRUNCATE(b / 1000, 3), TRUNCATE(b / 1000, 2))
AS b
if(a<1,2,3) means if a<1 then 2 will come as a value in your result so you have to switch your values position
use round
SELECT a , IF(b < 10, round((b / 1000), 2), round((b / 1000), 3) ) AS b
The ROUND() function rounds a number to a specified number of decimal places.
example SELECT ROUND(345.156, 2); result = 345.16
SELECT ROUND(345.156, 2); result = 345.156
If you don't want round then TRUNCATE will shown 0.00 in case of b value less than 10, so what do you mean by not working ?
You need 3 decimal place when b<10 so you have to change the position of yours query result
You have misplaced the order of queries to run, in case of true/false evaluation in If(). Following may work:
SELECT `a `,
IF(`b ` < 10,
TRUNCATE(`b ` / 1000, 3),
TRUNCATE(`b ` / 1000, 2)
) AS `b `

Does mysql query cache the dynamically calculated columns

I have a mysql query:
SELECT my_table.* WHERE SOUNDEX(my_col)='whatever' OR SUBSTR(SOUNDEX(my_col),4)='whatever' ORDER BY SUBSTR(SOUNDEX(my_col),4)='whatever',SOUNDEX(my_col)='whatever'
How many times will the substring function and soundex functions will actually be called? I mean for exactly same inputs will mysql cache the results over the span of one query?
If not, how can I make the change in the query so that each function is called minimum times possible.
MySQL would call this function four times for every returned row, to avoid this you can use a subquery, so instead of
SELECT *
FROM song
ORDER BY Substr(pre_calculated_soundex, 1, 1) =
Substr(Soundex("aaaa"), 1, 1)
+ Substr(pre_calculated_soundex
, 2, 1) =
Substr
(Soundex("aaaa"), 2, 1)
+ Substr(pre_calculated_soundex, 3, 1)
= Substr(Soundex("aaaa"), 3, 1)
+ Substr(pre_calculated_soundex, 4, 1
)
= Substr(Soundex("aaaa"), 4, 1)
You can do
SELECT * from (select *, Soundex("aaaa") as current_soundex from song)
ORDER BY
Substr(pre_calculated_soundex, 1, 1) = Substr(current_soundex , 1, 1)
+ Substr(pre_calculated_soundex, 2, 1) = Substr(current_soundex , 2, 1)
+ Substr(pre_calculated_soundex, 3, 1) = Substr(current_soundex , 3, 1)
+ Substr(pre_calculated_soundex, 4, 1) = Substr(current_soundex , 4, 1)

MySQL - my months are current stored 0-11

I thought I ran into a bug with MySQL 5.1, but the bug was in the perl code that's creating the timestamps. perl's localtime uses 0-11 for months, but MySQL's datetime uses 1-12. So, I've got all these malformed timestamps that I need to update.
2012-00-19 09:03:30
This should be:
2012-01-19 09:03:30
The problem is that the date functions for MySQL return NULL on a 00 month. Is there a way to do this in MySQL?
EDIT: Solution =
UPDATE test_stats
SET start_time = CAST(CONCAT(SUBSTRING(start_time, 1, 5),
CAST((CAST(SUBSTRING(start_time, 6, 2) AS UNSIGNED) + 1) AS CHAR(2)),
SUBSTRING(start_time, 8, 12)) AS DATETIME);
By the way, I was using MySQL 5.1
This should work:
UPDATE MyTable
SET DateTimeField =
CAST (
SUBSTRING(DateTimeString, 1, 5) -- '2012-'
+ CAST((CAST(SUBSTRING(DateTimeString, 6, 2) AS INT) + 1) AS VARCHAR) -- '00' => '1'
+ SUBSTRING(DateTimeString, 8, 12) -- '-19 09:03:30'
AS DATETIME)
Test with this select
DECLARE #x VARCHAR(50) = '2012-00-19 09:03:30'
SELECT CAST(SUBSTRING(#x, 1, 5)
+ CAST((CAST(SUBSTRING(#x, 6, 2) AS INT) + 1) AS VARCHAR)
+ SUBSTRING(#x, 8, 12) AS DATETIME)

Concat different tables?

I need to concatenate from two different tables.
Compare s.panelid (result like "AA") to b.modulecodes and return number_of_strings. Then put s.panelid (result like "AA") and number_of_string together.
select concat(Mid(s.panelid, 5, 2), ' - ' , '??') as `Module Type-Strings`
from r2rtool.stringtopanel s, be.modulecodes b
where s.insertts > '2011-07-15' and s.insertts < '2011-07-26' and Mid(s.panelid, 5, 2) != 99
group by date(insertts), `Module Type-Strings`
order by `Module Type-Strings`;
Be (Table): modulecodes, number_of_strings
AA - 12
AB - 4
AD - 3
AE - 12
When I run the above query it returns things like: Module Type-Strings = 'AA-??' and "AB-??" of course.
I am looking for: Module Type-Strings = 'AA-12'
Just in case you haven't tried it already...
Have you tried this?
select concat(Mid(s.panelid, 5, 2), ' - ' , b.number_of_string) as `Module Type-Strings`
from r2rtool.stringtopanel s, be.modulecodes b
where s.insertts > '2011-07-15' and s.insertts < '2011-07-26' and Mid(s.panelid, 5, 2) != 99
group by date(insertts), `Module Type-Strings`
order by `Module Type-Strings`;
There I'm basically replacing the '??' with the column you are asking about, number_of_string in the be.modulecodes table (aliased as b in the from clause).