Convert decimal stored as varchar to datetime - mysql

I've inherited a MySQL database with a date column type of Varchar.
The column contains decimal strings. For example: 41143.646585648.
How would I go about converting this into DateTime format?

All you need to know is the date the original developer defined as the value zero. Then it's a simple matter of adding the integer number of days to that date, then multiplying the fractional part by 86400 to get seconds and doing the arithmetic to determine the hour, minute and second.
If you have a row where you know the actual date and the stored value you can determine the zero date easily by subtraction.

You could string replace the dot, but the remaining count of numbers is to high for a unix timestamp. I don't know how the date was converted to decimal. Maybe you should split your string rather than string replace.
Maybe this code gives you some ideas for a solution:
#SELECT FROM_UNIXTIME(REPLACE('41143.646585648', '.', '')); # Does not work due to wrong amount of numbers in string
SELECT FROM_UNIXTIME(REPLACE('13577.77916', '.', '')); # works

Related

Converting string column to timestamp in BigQuery?

I am trying to convert a column in a BQ table to timestamp. I have two string columns, one for utc_hour (string 0-23) and utc_day (string yyyymmdd) imported from a public data source. I merged the two columns to produce a string column, utc_timestamp, with strings like this - "20171208 500" .
I need to convert that string into timestamp, and when I use
TIMESTAMP(utc_timestamp)
I get the error message
Invalid timestamp: '20171208 500'
I tried using dataprep, which also could not convert that string to a timestamp.
How can I convert this format to a timestamp?
Try to parse with %Y%m%d%k%M format.
PARSE_TIMESTAMP("%Y%m%d%k%M", utc_timestamp)
This question is already answered but in case someone else visits here with his/her own unique timestamp format (in which case the accepted answer might not work), you need to follow the notations on this documentation page
For eg, in my case values were like this 2020-05-11-00:00:00. So, I went to the above-mentioned page and found that the format string that I needed would be something like %Y-%m-%d-%H:%M:%S.
I will put the description for the ones that I used in my format string:
%d The day of the month as a decimal number (01-31).
%H The hour (24-hour clock) as a decimal number (00-23).
%M The minute as a decimal number (00-59).
%m The month as a decimal number (01-12).
%S The second as a decimal number (00-60).
%Y The year with century as a decimal number.
The :s and the -s are quite self-explanatory.

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 5.6 calculation with datatype time within function returns wrong value - but outside is ok

I use mySQL 5.6 on Windows 7 Pro x64 and have the following problem.
SELECT fee(100, '12:00:00');
returns 500,000 which is obviously not correct.
But
SELECT 100 * '12:00:00'/24;
returns the correct result which is 50.
DROP FUNCTION IF EXISTS fee;
DELIMITER //
CREATE FUNCTION fee(price INT, duration TIME)
RETURNS DECIMAL(15,2)
BEGIN
RETURN price * duration/24;
END //
DELIMITER ;
Have you ever encountered this problem? What is the reason behind it?
Thanks for any hints for solving this.
My guess is that in 100 * '12:00:00'/24 expression '12:00:00' is evaluated as string, not as a time expression, and in '12:00:00'/24 operation the string is converted to a number, so it is executed as 12/24, which gives the expected result.
However, when the fee() function is called, '12:00:00' is passed to a parameter with TIME data type. In the duration/24 operation duration is converted to integer first, then the division is executed. However, select cast(cast('12:00:00' as time) as integer) conversion yields 120000, not 12. 120000/24*100=500000 - this is the output received from the original function. According to mysql documentation on TIME:
Be careful about assigning abbreviated values to a TIME column. MySQL
interprets abbreviated TIME values with colons as time of the day.
That is, '11:12' means '11:12:00', not '00:11:12'. MySQL interprets
abbreviated values without colons using the assumption that the two
rightmost digits represent seconds (that is, as elapsed time rather
than as time of day). For example, you might think of '1112' and 1112
as meaning '11:12:00' (12 minutes after 11 o'clock), but MySQL
interprets them as '00:11:12' (11 minutes, 12 seconds). Similarly,
'12' and 12 are interpreted as '00:00:12'.
Although the documentation describes integer to time conversion, it is safe to assume that time to integer conversion works the same way. I would use price * time_to_sec(duration)/86400 to get the right result.
Thank you all for your helps and comments.
#Shadow, #B98 – you are right. The problem has to do with converting '12:00:00' to its corresponding numeric value.
I searched a lot about how MySQL performs converting time to number in general, however I didn't find anything.
So I started a little bit experimenting on it and this is what I found out about it yet:
The default datatype in MySQL is VARCHAR, so every value/"variable" which has no explicit datatype its datatype is VARCHAR(length of value/variable) as you've correctly guessed, Shadow.
Converting VARCHAR to a numeric datatype works generally like this: take all digits from the left of the string up to the point you find a character except 0-9. If immediately after the digits there is a dot “.”, take the dot as the decimal point and continue searching for decimal digits till the string ends or you find a character except 0-9.
So in short: take from the left of the string what matches the pattern [0-9][.[0-9]] and throw the rest of it away – as you mentioned it, B98. Examples: '12:30:59' = 12; '12whatever30whatever59' = 12; '12.30.59' = 12.30; '12.30whatever' = 12.30
However, converting TIME to a numeric datatype works a little bit different: First remove the colons then convert it to an integer. Exempels: '12:00:00' = 120000; '12:30:59' = 123059
Converting DATETIME to a numeric datatype works the same way as converting TIME to numeric, except here get the dashes in the date part, the space between date and time and the colons in the time part removed and then gets the whole string converted to an integer. Exempels: '2015-12-24 12:59:59' = '20151224125959'
Below you find a query which shows this behavior of MySQL.
DROP VIEW IF EXISTS datetimeTypes;
CREATE VIEW datetimeTypes AS
SELECT
'12:59:00.50' AS timeImplicit,
CAST('12:59:00.50' AS TIME) AS timeExplicit,
'12:59:00.50' / 1 AS timeImplicitDiv,
CAST('12:59:00.50' AS TIME) / 1 AS timeExplicitDiv,
'2015-12-24 12:59:59' AS datetimeImplicit,
CAST('2015-12-24 12:59:59' AS DATETIME) AS datetimeExplicit,
'2015-12-24 12:59:59' / 1 AS datetimeImplicitDiv,
CAST('2015-12-24 12:59:59' AS DATETIME)/1 AS datetimeExplicitDiv;
SHOW FIELDS FROM datetimeTypes;
SELECT * FROM datetimeTypes;

MySql YYYY-MM-DDTHH:MM:SS to time

I have a table with a varchar column DateFrom that has this format:
2014-02-22T08:08:00
I want an sql that prints 08:08 and one that prints 22-02-2014 but i can't seem to get the time function to work.
What i'm trying to do is get all entries in DateFrom and print them as just time (HH:MM)
and the same with date.
Altough I think string functions are a better option in this case (like #hakre answered) and less cpu expensive, you can also achieve this goal using the STR_TO_DATE, DATE and TIME function.
SELECT
DATE(STR_TO_DATE('2014-02-22T08:08:00', '%Y-%m-%dT%H:%i:%s')),
TIME(STR_TO_DATE('2014-02-22T08:08:00', '%Y-%m-%dT%H:%i:%s'))
If you're not looking for date/time but for string functions, they are available here:
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html
One string function that I think is useful for your substring operation is SUBSTRING. You can tell per the varchar column that you want a sub-string starting from a position for a certain length with it:
SUBSTRING(DateFrom FROM 1 FOR 8) AS DateName -- "2014-02-22"
SUBSTRING(DateFrom FROM 10 FOR 5) AS TimeName -- "08:08"
Use other string functions to concatenate parts in the order you need it.
Alternatively you can cast your varchar string in that format to a datetime type and then format as needed:
CAST(DateFrom AS datetime)
See the Mysql manual for more information about casting types and the date-time functions that are available:
http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html
SQL Example:
SET #DateFrom = '2014-02-22T08:08:00';
SELECT DATE(CAST(#DateFrom AS datetime)); -- '2014-02-22'
SELECT TIME(CAST(#DateFrom AS datetime)); -- '08:08:00'

Decimal datatype is rounding the values

I have set my MySQL field table data type to the decimal because from what I have read, I would be able to store the price with commas/dots in the decimal data type fields... The problem is that whenever I store any data with the comma or dot, MySQL is rounding it automatically up or down. Eg. When I'm executing the following query:
UPDATE table SET field = 114.21 WHERE id = 1;
Then field is set, but the value is rounded to 114, instead of displaying the data I set in the query (114.21) - is there any solution for that? Or I should just use other data type?
AFAIK the dot is the standard notation for decimal values. Using Commas may trigger SQL parse errors or may go unnoticed if the syntactical context allows for a comma to be there.
How did you define the precision of the DECIMAL column?
If it is DECIMAL(10, 2) it will have a total of 10 numbers of which 2 are decimal values (with 2 decimal rounding meaning that 10.215 is saved as 10.22 and 10.214 becomes 10.21).
If it is DECIMAL(10) it will not have any decimal values and be rounded to an integer.
If you use FLOAT or DOUBLE PRECISION you don't have to specify the number of decimal values but it has its own flaws.
As Mihai mentioned you need to define the proper precision for the decimal type, e.g. DECIMAL(10,2) for two decimal places.
When inserting a decimal value mySQL will round.
From the docs:
For inserts into a DECIMAL or integer column, the target is an exact data type, so rounding uses “round half away from zero,” regardless of whether the value to be inserted is exact or approximate.
See http://dev.mysql.com/doc/refman/5.0/en/precision-math-rounding.html for details.
Well before I have also an issue regarding on what to use on my numbers with decimal points. But problem solved by using DOUBLE(10,2) as my DATATYPE, and it shows the exact number on the database when you save it. Hope it will help.