MySQL STR_TO_DATE problem - mysql

I've got the following part of a query:
STR_TO_DATE(CONCAT(g.Year,',',g.Month,',',g.Day),'%Y,%m,%d') AS HelpDate
g is a table of course. I know the values of g.Year, g.Month and g.Day all work fine because if I take out the STR_TO_DATE call and just use:
CONCAT(g.Year,',',g.Month,',',g.Day) AS HelpDate
it works fine. For some reason mysql breaks with the addition of the STR_TO_DATE. As far as I can tell this should work. I even tried hard coding the date just to force it to make sure I wasn't crazy:
STR_TO_DATE('2011,9,2','%Y,%m,%d') AS HelpDate
That didn't work either
Edit:
Ok. So the reason STR_TO_DATE wouldn't work at all for me was because the server was running MySQL 4.0. I've since moved the database to a MySQL5 server. Now, here's my problem. STR_TO_DATE only works as long as I'm not trying to concatenate table references. For example, both of these work:
STR_TO_DATE('2011,9,2','%Y,%m,%d') AS HelpDate
STR_TO_DATE(CONCAT('2011',',','9',',','2'),'%Y,%m,%d') AS HelpDate
However, this still does not:
STR_TO_DATE(CONCAT(g.Year,',',g.Month,',',g.Day),'%Y,%m,%d') AS HelpDate
I get this error:
#1305 - FUNCTION db380975735.STR_TO_DATE does not exist
db38097573 is the name of the database

You're looking for the format '%Y,%c,%e'. %m and %d matches the month/day when it begins with a zero (it would match 2011,09,02).
By the way, what's the point to store the year, month and day separately? Store it in a DATE type, and use the functions YEAR(), DAY() and MONTH() if necessary.

Try using:
STR_TO_DATE('2011,9,2','%Y,%c,%e') AS HelpDate
%m and %d assume formatting with leading zeroes, i.e. numbers that are always two digits long. Thus STR_TO_DATE('2011,09,02','%Y,%m,%d') AS HelpDate would probably work. %c and %e refer to the variable-length numeric month and day respectively.

Related

STR_TO_DATE() returns wrong data from right format

Using MySQL 5.7, it's pretended a conversion from strings representing four-digit year followed by two-digit month with no any other character in the middle.
For example, running the following statement
SELECT str_to_date('202105','%Y%m');
What is returned: 160101 being January 1601 instead of May 2021. The required arguments seem correct considering the function in cause.
I was not able to reproduce your exact result on DBFiddle, but I did see it creates a null instead of the expected date. What you can do is append a '01' to get a better date literal:
SELECT str_to_date(concat('202105', '01'),'%Y%m%d');
See it here:
https://www.db-fiddle.com/f/sbArVsLF6BVDGSrYdy8geP/0
You need to specify the day as well, otherwise it won't work in MySQL 8.0+.
You need all parts of the date i.e. year, month and day must be specified for the function to operate properly.
# Incorrect Code:
SELECT str_to_date('202105','%Y%m');
# Correct Code:
SELECT str_to_date('20210501','%Y%m%d');
Outputs
2020-05-01
Ref: https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_str-to-date

MySQL timestamp format and datediff

Hi I'm writing queries for MySQL, and now my database has a column containing the timestamp in this format: 7/14/2015 7:57:49 AM, but I need to use the DATEDIFF function, so how can I convert the timestamp into the format like: 2015-7-14 (or 2015-07-14, I'm not sure which one is correct; just the date)?
This should convert your string to just the date in a date format, then you can use DATEDIFF on the date fields in question:
SELECT STR_TO_DATE(LEFT(t,LOCATE(' ',t) - 1), '%m/%d/%Y') FROM my_table;
The LEFT function will take the substring to the left of the space, which is just your date, then STR_TO_DATE will convert that substring to a date the system can use.
(Not knowing your field and table names, I used t and my_table.)
You don't need to. The way MySQL displays timestamps has nothing to do with the way they're stored internally; as long as it's TYPE TIMESTAMP or some compatible type, the DATEDIFF() function will know what to do with it.
TIMESTAMPs are actually stored as a really huge integer representing (I think) milliseconds from Midnight UTC, January 1st, 1970. The display format is determined by a system global variable, and has nothing to do with the actual value.
Converting from a string to a DATETIME or TIMESTAMP is actually also fairly straightforward using the STR_TO_DATE() function; in your case the format string would be something like
STR_TO_DATE('%c/%e/%Y %l:%i:%s %p', datecol)
although you might have to experiment a bit to make it work reliably.

MySQL SEC_TO_TIME gives hh:mm:ss.000000

As said in the caption I am wondering why the SEC_TO_TIME-Function of MySQL gives me that Zeros at the end.
Refering to the docu (http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_sec-to-time) that shouldn't happen (I am using MySQL 5.0.11).
Any Idea why this Zeros appears and how to get rid of them? To much zeros for displaying miliseconds.
Sine the zeros doens't break MySQLs Date-funcions, it's more a "I don't like that"-Question rather than a real Problem (at least till now^^)
// EDIT: I just figured out that the zeros aren't coming from the SEC_TO_TIME but from the FROM_UNIXTIME()-Function. Thx to #Abhik Chakraborty to ask for the input!
// EDIT2: I used FROM_UNIXTIME(last_try, '%Y-%m-%d %H:%i:%s') to get rid of the zeros. But When I do TIME(FROM_UNIXTIME(last_try, '%Y-%m-%d %H:%i:%s')) the zeros are back. Why??
Seems like every function adds the zeros back. Using SEC_TO_TIME on a simple integer-value also gives zeros...
Here is the whole query iam using:
SELECT
SEC_TO_TIME(FLOOR(TIME_TO_SEC((TIME(FROM_UNIXTIME(`last_try`))))/1800)*1800)
FROM `last48h`
The query reads the timestamp, gets only the time, converts it to seconds, breaks the seconds into half-hours (/1800 gives 0 < x < 48) rounds down and converts back to time
SEC_TO_TIME produces a TIME data type for its result. You can format that as you wish with DATE_FORMAT.
If you actually need subsecond time resolution you'll need to move to version 5.6.4 or beyond.
When you directly SELECT any sort of TIME data type to display, you get a default TIME-to-string conversion operation. The default TIME-to-string conversion in some generations of MySQL yields a string ending in hh:mm:ss+zz00. +zz00 is a timezone indicator, and often displays as +0000. Any chance that's what you're seeing?
It doesn't make sense to try to handle a UNIX_TIMESTAMP() style number of seconds using SEC_TO_TIME(). As of mid-2014 the current unix timestamp value is above 1.39 gigaseconds. TIME data types are used for stuff like elapsed times, and have a limit of just under 839 hours (3 megaseconds, precisely 3020399 seconds), and silently truncate their values.
For example, this is a good use of SEC_TO_TIME:
SELECT SEC_TO_TIME(end_timestamp - start_timestamp) AS duration
edit
Strangely enough, this query
SELECT
SEC_TO_TIME(FLOOR(TIME_TO_SEC((TIME(FROM_UNIXTIME(UNIX_TIMESTAMP()))))/1800)*1800) AS a,
FLOOR(TIME_TO_SEC((TIME(FROM_UNIXTIME(UNIX_TIMESTAMP()))))/1800)*1800 AS b,
TIME_TO_SEC((TIME(FROM_UNIXTIME(UNIX_TIMESTAMP()))))/1800 AS c,
FROM_UNIXTIME(UNIX_TIMESTAMP()) AS d,
FROM_UNIXTIME(UNIX_TIMESTAMP() - UNIX_TIMESTAMP() % 1800) as e
doesn't show any of the 0000 stuff through the phpmyadmin instance I use.
By the way, most people who round time to the nearest interval (a half-hour in your case) prefer to use a modulo and a subtraction; it's less dependent on implicit numerical type conversion than your method.
SELECT TIME(FROM_UNIXTIME(last_try - last_try%1800))
does what the query in your question does.
I had the same problem with the 'SEC_TO_TIME' function.
I had overlooked the fact that I was storing timestamps as a VARCHAR.
I changed my datatypes from VARCHAR to BIGINT and it is formatting the output values as expected (hh:mm:ss).
Try to use TIME_FORMAT with %k specifier it should help.

Weird Date MySQL INSERT statement (vb.net app but MYSQL command)

I've got a really random bug in my code somewhere but can't figure it out. I'm inserting data into a MySQL Database based the current date and use the following statement;
INSERT INTO table VALUES (NULL,495297,str_to_date('19/01/2013 10:55:25','%d/%m/%y'),'English - UK',1,Str_to_date('17/01/2013','%d/%m/%y'),str_to_date('18/01/2013','%d/%m/%y'))
none of the dates work as the 19/01/2013 for some reason it becomes 19/01/2020, the next become 17/01/2020 and 18/01/2020! The latter two dates are listed as Date in data Type whereas the first date is DateTime so I don't know why this bizarre problem is happening.
Any help would be greatly appreciated.
Thanks
Maudise
Use a capital %Y as identifier for the year:
INSERT INTO table VALUES (NULL,495297,str_to_date('19/01/2013 10:55:25','%d/%m/%Y'),'English - UK',1,Str_to_date('17/01/2013','%d/%m/%Y'),str_to_date('18/01/2013','%d/%m/%Y'))
The lower case %y specifies a year given by two digits (see MySQL documentation here and here). The uper-case %Y, however, is the four-digit version.

why this MySQL SELECT doesn't include the right dates?

The main problem is, that I have stored in database datetime , not the date (what I need). Ok never mind.
I have thousands of reports stored each day.
I need to LEFT by 10 my datetime_view (to cut the time) and everything's fine. Except this. I'm trying to figure out why do I have to put in the condition + one day from the future? Otherwise it won't search what I want.
SELECT
LEFT(datetime_view,10),
count(type)
FROM reports
WHERE
type IN (1,2,5)
AND
datetime_view>='2012-10-28'
AND
datetime_view<='2012-11-04'
group by LEFT(datetime_view,10);
You can see I must search from the future. Why??
It gives me an output from 28.10 to 3.11 ....
don't use string operations on date/time values. MySQL has a huge set of functions for date/time manipulation. Try
GROUP BY DATE(datetime_view)
instead, which will extract only the date portion of the datetime field. Your string operation is not y10k compliant. Using the date() function is.
As for your plus one day, consider how the comparisons are done: A plain date value, when used in date/time comparisons, has an implicit 00:00:00 time value attached to it, e.g. all dates have a time of "midnight".
i think it's better to use DATE(datetime_view) to cut the time instead of LEFT(datetime_view,10), also on the where condition:
DATE(datetime_view) <= '2012-11-03'