How to Auto Increment Part of Varchar - mysql

I trying to create a query to auto increment a Varchar column. The number values is a date value, highlighted, are the numbers I'm trying to increment by 7. Is there a way to auto increment the number/date value within the number column?
From
select * from table_name where number = 'ABC**070516**A001'
To
select * from table_name where number = 'ABC**071216**A001'

If you have the option to do it outside of MySql - do it.
If you know exactly the format of your numbers - 3 letters + date + something else you can do this:
REPLACE('ABC070516A001', MID('ABC070516A001', 4, 6), DATE_FORMAT(DATE_ADD(STR_TO_DATE(MID('ABC070516A001', 4, 6), '%m%d%y'), INTERVAL 7 DAY), '%m%d%y'))
It will do the following:
Extract the date number - MID('ABC070516A001', 4, 6) This suggests that it always has 3 letters in the beginning. If the format is more complex you will need a library with regex replace function
Converts the extracted number to Date object STR_TO_DATE('070516', '%m%d%y')
Adds interval of 7 days to the date object. This will handle all the cases like transition to new month and new year. DATE_ADD('2016-07-05', INTERVAL 7 DAY)
Formats the result date to your number format DATE_FORMAT('2016-07-12', '%m%d%y')
Replaces the number with the new number REPLACE('ABC070516A001', MID('ABC070516A001', 4, 6), '071216')

Well, in your queries you are not incrementing anything. You are making two selects. If you wanted to change the value of a varchar column to be auto increment it's not possible. At least not with out lot's and lot's of code.
The simplest solution for you is to create three separate columns and to make the third one auto increment.
col1 col2 col3
ABC 070516 A001
ABC 071216 A001
Then concatenate the columns at the time of retrieval/display.

Related

SUBSTRING_INDEX Not Warking in Mysql

I am trying to find max invoice:
SELECT IFNULL(MAX(SUBSTRING_INDEX(invoice,'I', -1)) + 1, 1) AS invoice
FROM sales
SQL Fiddle
When I run this SQL query, it can not count more than 10.
invoice
20221026P1I1
20221026P1I2
20221026P1I3
20221026P1I4
20221026P1I5
20221026P1I6
20221026P1I7
20221026P1I8
20221026P1I9
20221026P1I10
20221026P1I11
20221026P1I12
I am trying to find max invoice 12 + 1 = 13
Your use of SUBSTRING_INDEX() is correct, however you should cast the string value to a bona fide integer:
SELECT COALESCE(MAX(CAST(SUBSTRING_INDEX(invoice, 'I', -1) AS UNSIGNED)), 1) AS invoice
FROM sales;
The problem with trying to find the max of the text substrings themselves is that text numbers sort lexicographically, e.g.
1
10
11
2
23
But this isn't the behavior you want, you want the numeric maximum. Hence we should cast these substrings and then compare.
Side note: You could have avoided this problem entirely by maintaining a pure numeric invoice number column. You may want to change your table design to include such a column.

Retreat Weeks/Months/Years from a simple date Input

Considering the date "2018-01-29" (VAR_5) as a single input,
SELECT
DATE_FORMAT('2018-01-29','%v/%Y') AS VAR_5,
DATE_FORMAT('2018-01-22','%v/%Y') AS VAR_4,
DATE_FORMAT('2018-01-15','%v/%Y') AS VAR_3,
DATE_FORMAT('2018-01-08','%v/%Y') AS VAR_2,
DATE_FORMAT('2018-01-01','%v/%Y') AS VAR_1,
DATE_FORMAT('2017-12-25','%v/%Y') AS VAR_0
How can I go back in time only from that date?
Instead of manually entering the remaining dates? ('2018-01-22','2018-01-15','2018-01-08','2018-01-01','2017-12-25')
I need something like an Loop inside mysql ...
** In this case I want to retreat Weeks .
Intended Output:
enter image description here
Given a sequence table containing integer values (eg. helper.seq(i) with values 1, 2, 3, ...) you can do the following:
select '2018-01-29' - interval (s.i-1) week as dt
from helper.seq as s
where s.i <= 6
Demo: http://rextester.com/SOA75169
You can replace week with day, month or year.

MySQL: Getting&assigning number from a column of strings

The table contains a column that contain strings. I would like to extract numbers from the string.
The code: http://sqlfiddle.com/#!9/2af45
Eg:
1 Day = 1
2 Day anytime = 2
7 Days = 7
SameDay = 1
As for string that does not contain any number, I would like to assign a number to it.
What I have in mind:
What will be the best solution such that the query will not affect the loading speed greatly on MySQL?
Additional challenge: If the number appears randomly in the string, is there any method/algorithm that can potentially pull the number?
E.g. every 2 day, promotion in 7 days
If the string starts with a number, you can simply CAST it to an UNSIGNED. Any text after the number is ignored
CAST("2 Day anytime" AS UNSIGNED);
CAST("20 fishes" AS UNSIGNED);
Any string that doesn't start will a number, will become 0. You can turn that into some other value with the combination of NULLIF and IFNULL.
IFNULL(NULLIF(CAST("SameDay" AS UNSIGNED), 0), 1);
You can create a new column with ALTER TABLE and than do an UPDATE query.
UPDATE foo (days_int)
SELECT IFNULL(NULLIF(CAST(days_string AS UNSIGNED), 0), 1)
FROM foo;
Note that the update and select is from the same table.

Querying Comma Delimited Values in MySQL

I need a way to query a collection of data. I have a list of recent activity dates each stored in 1 row per user. Each row has a field of loginDates which consists of a comma separated list of timestamps.
What i need to do is run reports on this date to find people active since XXXXXX timestamp. The problem is the fact it's comma separated means i can't query it uses methods i know.
Here is an example row
id userID accessDates
2 6 1399494405,1399494465,1399494525,1399494585,1399494623
What i want to achieve in plain text
SELECT all_fields FROM accessTable WHERE accessDate > YESTERDAY
ALSO These dates may however span over several hundreds of days with hundreds of timestamps in the field.
Assuming the TimeStamp values are in order as your data sample shows, if any of the TimeStamp values in the string are greater than a given date, then the latest one would be greater than that value as well. So you only need the latest TimeStamp value to meet your requirement:
SET #Yesterday =
UNIX_TIMESTAMP(DATE_ADD(DATE(CURRENT_TIMESTAMP()),INTERVAL -1 DAY));
SELECT *
FROM accessTable
WHERE CAST(RIGHT(accessDates,10) AS UNSIGNED) > #Yesterday;
If you want to query each of those TimeStamps individually, the best solution is to put them into a single table column with a userid:
userID accessDate
------ ----------
6 1399494405
6 1399494465
6 1399494525
6 1399494585
6 1399494623

MySQL pattern matching with character exception

I'm trying to compare the results of two queries, one acquiring call IDs for calls made to my Asterisk server externally (10 digits) and the other acquiring call IDs connected to FROM the server (11 digits). The outbound calls are prepended a '1' before their number. Currently I'm using a statement like the following:
select data2, from_unixtime(time_id) day from queuemetrics.queue_log
where time_id > '1346475600' and (data2, time_id) in
(select dst, unix_timestamp(calldate) from asteriskcdrdb.cdr
where calldate > '2012-09-01' and lastdata like <blocked for privacy>)
order by day;
data2 is the column holding the 10 digit numbers, dst holds the 11 digit numbers. Is there a way I can pattern match the 2-11th characters of a column ONLY? To just skip over the first one? Obviously a LIKE or RLIKE would be useful, but I really need to maintain the nested query for this to work. Any help would be great. Also, pay no attention to my weird use of from_unixtime and unix_timestamp. I was experimenting with figuring if I needed my times in the same format for the search to work. Not important.
You may use RIGHT to extract the rightmost characters of a string:
RIGHT(your_field_here, 10);
If there are some characters you want to ignore at the beginning AND at the end of the string, then you may use SUBSTR:
SUBSTR(your_field_here, 2, 10);
Your query would then be:
SELECT data2, FROM_UNIXTIME(time_id) day FROM queuemetrics.queue_log
WHERE time_id > '1346475600' AND (data2, time_id) IN
(SELECT SUBSTR(dst, 2, 10), UNIX_TIMESTAMP(calldate) FROM asteriskcdrdb.cdr
WHERE calldate > '2012-09-01' AND lastdata LIKE <blocked for privacy>)
ORDER BY day;
Why not trim the leading digit from your dst field?