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.
Related
As title, I'm trying to convert a VARCHAR column in a DATE column, and data is populated in that format "DDMMYYYY" ex. XMAS is "25122022" and in this case the correct formula should be STR_TO_DATE(column, '%d%m%Y')Well, when I execute this query I get an error since in some cases I have values with a "missing" char, I mean, for example, "1012023" when the day is <10 the query fails, cause it checks for "01122023" instead.I could solve this easily by adding a 0 to all fields having length 7, but I'd like to make it more clean.Reading better the usage of STR_TO_DATE I noticed that I could replace %d with %e since the second choice should theorically consider days from 0 to 31 instead of 01 to 31.Unexpectedly the query didn't work and gave me the same erorr at the first instance of a length 7 string.Am I doing something wrong?Thanks in advance.
We can try left padding your date string with zero to a length of 8:
WITH yourTable AS (
SELECT '1012023' AS dt
)
SELECT STR_TO_DATE(LPAD(dt, 8, '0'), '%d%m%Y') AS dt_out -- 2023-01-01
FROM yourTable;
Demo
I am writing a query that is used by report generating software.
Part of this is querying for the hours needed to complete a project. We record this a 2 decimal float so that we can estimate to the quarter hour.
However, if we are using it in our report and the hour we recorded is something like 8.00, I want to query it and format it so that 8.00 is just 8. However any hours with something past the decimal, like 8.25, should remain as 8.25. How can I make this work?
hours Queried Result
====== -> My Query -> ==============
8.00 8
8.25 8.25
I am using MySQL 5.6
You can use the REPLACE() function to remove .00:
REPLACE(hours, '.00', '') AS hours
You can convert it to a string and check the rightmost 2 characters and trim those if they are '00'.
SELECT TRIM(TRAILING '.00' FROM CAST(column_name AS VARCHAR));
SELECT REPLACE(Round(8.00), '.00', ' ');
I will give more example so you can clear your Logic:
MySQL ROUND() rounds a number specified as an argument up to a number specified as another argument.
Syntax:
ROUND(N,[D]);
Where 'N' is rounded up to D decimal places.
and 'D' is indicating up to how many decimal places N will be rounded.
Example 1:-
SELECT ROUND(4.43);
Output :-
4
The above MySQL statement will round the given number 4.43. No decimal places have been defined, so the default decimal value is 0.
Example 2:-
SELECT ROUND(-4.53);
Output:-
-5
The above MySQL statement will round the given number -4.53. No decimal places have been defined, so the default decimal value is 0.
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.
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.
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?