Using INSERT ... SELECT with Date format - mysql

I am using an INSERT ... SELECT query in my MySQL. Now, in my database is a column named "medDate" which I use for my medicine Inventories app. This has a type Varchar and is formatted in this way, "July 2014". Now I want to use the insert...select query to copy the previous month's records. But as I test my query to MySQL, there's an error which says incorrect datetime value. Can you help me with this? This is my query.
INSERT INTO medicinesinventory (itemName, compCode, classID,
medDate, price, beginningIn, newIn,
outMed, sales) SELECT DISTINCT(itemName),
compCode, classID, CURDATE(),
price, 0.0, 0, 0.0, 0.0
FROM medicinesinventory
WHERE YEAR(medDate) = DATE_FORMAT(CURRENT_DATE - INTERVAL 1 MONTH, '%M %Y')
AND MONTH(medDate) = DATE_FORMAT(CURRENT_DATE - INTERVAL 1 MONTH, '%M %Y');
SAMPLE DATA
compCode medID classID medDate itemname price beginningIn newIn outMed sales
GOLDEN 148 20 July 2014 sample 0.00 0 0.00 0.00 6.00

The functions year() and month() require dates. You can get the dates using str_to_date() because MySQL supports "partial" dates (i.e. those without days. So, try this:
WHERE YEAR(str_to_date(meddate, '%M %Y')) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH) AND
MONTH(str_to_date(meddate, '%M %Y')) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
Alternatively, you seem to want to format the previous month in the same format and do the comparison. That can also work:
WHERE medDate = DATE_FORMAT(CURRENT_DATE - INTERVAL 1 MONTH, '%M %Y')

The YEAR() and MONTH() functions operate on expressions of datatype DATE, DATETIME and TIMESTAMP.
If those functions are used on a VARCHAR expression, I believe MySQL will perform an implicit conversion of the VARCHAR to DATE (or DATETIME), expecting format to be 'YYYY-MM-DD' (or 'YYYY-MM-DD %h:%i:%s')
I believe that's where the "incorrect datetime value" error is being thrown.
Just use an expression that generates the VARCHAR value you want to match 'July 2014', and compare the VARCHAR values:
WHERE medDate = DATE_FORMAT(CURRENT_DATE - INTERVAL 1 MONTH, '%M %Y')

As medDate is a string and not a DATETIME you can't use YEAR on this column, but you could convert the right side with DATE_FORMAT and to be consistent you should store the values in the same format.
INSERT INTO medicinesinventory (itemName, compCode, classID,
medDate, price, beginningIn, newIn,
outMed, sales) SELECT DISTINCT(itemName),
compCode, classID,
DATE_FORMAT(CURDATE(), '%M %Y'), -- formatted this date
price, 0.0, 0, 0.0, 0.0
FROM medicinesinventory
-- and converted those in the where clause
WHERE medDate = DATE_FORMAT(CURRENT_DATE - INTERVAL 1 MONTH, '%M %Y')
Note
It would be better, if you could change the data type of the medDate column to DATE.

Related

Sort on string as date on MySql

I have CHAR strings stored in the database field in the format mm/dd/yyyy. Such as
2/26/2022
2/19/2022
2/12/2022
2/5/2022
12/31/2021
12/18/2021
11/27/2021
I need to sort them as shown according to the "date" without changing the declaration.
The post at MySQL date format DD/MM/YYYY select query? suggested using ORDER BY STR_TO_DATE(datestring, '%d/%m/%Y')
My MySQL statement looks like this:
SELECT stringdate
FROM mytable
WHERE product = '#myproduct#'
ORDER BY STR_TO_DATE(stringdate, '%m/%d/%y') DESC
However, the result is not sorted properly. Instead of the desired order as shown above, it is showing like this:
12/31/2021
12/18/2021
11/27/2021
2/26/2022
2/19/2022
2/12/2022
2/5/2022
It seems that the year is being ignored. How can I sort this without actually changing the database field declaration?
Thanks in advance.
2/5/2022 is month and day without leading zeros, and four digit year. The format string you have specified is -
%m - Month, numeric (00..12)
%d - Day of the month, numeric (00..31)
%y - Year, numeric (two digits)
SELECT stringdate
FROM mytable
WHERE product = '#myproduct#'
ORDER BY STR_TO_DATE(stringdate, '%c/%e/%Y') DESC
%c - Month, numeric (0..12)
%e - Day of the month, numeric (0..31)
%Y - Year, numeric, four digits
Executing the following query shows the difference in the converted dates -
SELECT
stringdate,
STR_TO_DATE(stringdate, '%m/%d/%y'),
STR_TO_DATE(stringdate, '%c/%e/%Y')
FROM mytable
WHERE product = '#myproduct#'
ORDER BY STR_TO_DATE(stringdate, '%c/%e/%Y') DESC
db<>fiddle
https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format
%y is the two-digit year code. So you are sorting them all as '20'
%Y is the four-digit year code.
See reference for the date format codes here: https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format
I recommend you use the DATE data type instead of CHAR.

SELECT records with date in format 'YYYY-MM' into given range

I want to fetch all the products which are near to "expire".
Date format on expiry date column exDate is (Y-m) or YYYY-MM, for example: 2018-03.
I am trying with this query but it fetches all record from the table.
SELECT * FROM product WHERE (exDate BETWEEN DATE_FORMAT(NOW() ,'Y-m') AND NOW()+ interval 2 month)
Turn exDate from the YYYY-MM format into the mySql date format YYYY-MM-DD then perform the query on that value:
SELECT * FROM product WHERE STR_TO_DATE( `exDate`, "%Y-%m" ) BETWEEN CURDATE() AND DATE_ADD( CURDATE(), INTERVAL 2 MONTH)
Take exDate and turn into mySql date format YYYY-MM-DD with
STR_TO_DATE( `exDate`, "%Y-%m" )
Note the % symbol is needed to specify the format.
Then this is the value that must fall into the interval.
Note you can just use CURDATE() to get the current date into date format.
To add a time interval to a date you have to use the mySql function DATE_ADD()
Note that as of today 2018-03-17 you will catch products with exDate with values 2018-04 and 2018-05.
2018-03 is not part of the results as it's turned into 2018-03-01 and is before today (the lower limit).
2018-05 is part of the results because it's turned into 2018-05-01 and is before the upper limit DATE_ADD( CURDATE(), INTERVAL 2 MONTH) that evaluates to 2018-05-17

MYSQL - DATE/TIME show last 30minutes

I have a column (lastlogin) that contains the following value = '17th May 2017 09:40:43 AM' ----
php function to create stamp:
date('jS F Y h:i:s A');
How can I do a select query that shows the (lastlogin) in that last 30 minutes from current time?
I'm guessing we have to convert date/time to string and separate the 2?
Any help would be amazing.
UPDATE:
I've tried the following but did not work returned more aless of records in table:
SELECT user_id, ('lastlogin' >= DATE_FORMAT(NOW() - INTERVAL 30 MINUTE,'%D %M %Y %H:%m:%s %p')) as result
FROM login_last
where lastlogin >= DATE_FORMAT(NOW() - INTERVAL 30 MINUTE,'%D %M %Y %H:%m:%s %p')
GROUP BY user_id
TABLE Structure
[id] int(8)
[user_id] int(11)
[lastlogin] varchar(30)
[browser] varchar(300)
You will need to convert your string date to a datetime format for the comparison, then compare the current datetime to the value stored.
You could also convert them to sortable strings for comparison. Something like "2017-05-17 10:20:10 AM", but it's easier to compare using the datetime type.
Reference:
str_to_date
date_format
MySQL Query:
SELECT
`user_id`,
`last_login`,
(STR_TO_DATE(`lastlogin`,'%D %b %Y %h:%i:%s %p') >= (NOW() - (INTERVAL 30 MINUTE))) as `in_range`
FROM `login_last`
WHERE (STR_TO_DATE(`lastlogin`,'%D %b %Y %h:%i:%s %p') >= (NOW() - (INTERVAL 30 MINUTE)))
SELECT * FROM tablename WHERE lastlogin >= DATE_SUB(NOW(), INTERVAL 30 MINUTE);
The challenge is to convert the result of DATE_SUB(NOW(), INTERVAL 30 MINUTE) to the correct format '17th May 2017 09:40:43 AM' (or format the left condition alias your lastLogin to UNIX_TIMESTAMP / datetime). In case you are inserting the date values yourself you probably already know how to get that format and can complete that yourself. Otherwise I recommend you to create a new question which is about formatting UNIX_TIMESTAMPs to your desired format.
A blind guess without having the chance to try that on my on would be:
SELECT * FROM tablename
WHERE UNIX_TIMESTAMP(lastlogin) >= DATE_SUB(NOW(), INTERVAL 30 MINUTE);

MYSQL: how can I get the day of week, month of year from date whose datatype is char(10)

The datatype of date column in my table is char(10). So each date is stored as a string like '02/01/2016/'.
How can I get the day of week and month of year from this '02/01/2016' in mysql?
Convert the string to DATE datatype using STR_TO_DATE function, and then use DATE_FORMAT function.
SELECT DATE_FORMAT( STR_TO_DATE( '02/01/2016', '%m/%d/%Y'), '%w') AS dow
, DATE_FORMAT( STR_TO_DATE( '02/01/2016', '%m/%d/%Y'), '%c') AS moy
(The format specifier needs to match the format of the string. This demonstration assumes that the string is in month/day/year format, that this represents February 1st, and not January 2nd.)
If you want to return a string like 'Monday', use '%W' in place of '%w'
MySQL Reference Manual:
http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format
http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_str-to-date
As #paxdiablo commented, you should seriously consider storing your date information as date, datetime, or timestamp. That being said, if you must live with your current setup, you can work around this by first parsing your text into a date using STR_TO_DATE() and then extracting out a string weekday and month name using DATE_FORMAT(). Something like this should work:
SELECT DATE_FORMAT(STR_TO_DATE(date, '%d/%m/%Y'), '%W') AS day_of_week,
DATE_FORMAT(STR_TO_DATE(date, '%d/%m/%Y'), '%M') AS month_of_year
FROM yourTable
Demo here:
SQLFiddle

How to parse English string dates in MySQL?

In my SQL database Valid Up To : Thursday, January 01, 2015 3:17 AM is stored as string with column name valid time. Now I want to select data which are updated in last one hour. How can I make a suitable query?
You can parse the string and convert it to a date with STR_TO_DATE(). Parsing options are described here.
SELECT
*
FROM your_table
WHERE STR_TO_DATE(`valid time`, 'Valid Up To : %W, %M %d, %Y %l:%m %p') >= NOW() - INTERVAL 1 HOUR;