Redshift - Convert epoch string to timestamp - mysql

I have got a table with 2 columns epoch_start and epoch_end.
I want to find the difference in days of these 2 epochs.
The problem i am facing is that the above columns are character varying(5000) type.
The query im running is
select datediff(day,'1459762341','1450762341') as numdays;
The error i get is
ERROR: invalid input syntax for type timestamp: "1459762341"

I have found the solution -
To get timestamp from epoch -
SELECT (TIMESTAMP 'epoch' + '1459762341' * INTERVAL '1 Second ') as
mytimestamp
For datediff between two epochs -
select datediff(day,(TIMESTAMP 'epoch' + '1458762341' * INTERVAL '1 Second '), (TIMESTAMP 'epoch' + '1459762341' * INTERVAL '1 Second ')) as numdays;

"epoc" time is just the number of seconds from 1/1/1970, so its just some counter of the number of seconds from that date.
So, epic_start can really be thought of as start_seconds, and epic_end is really just end_seconds.
The fact that they are the count of the number of seconds from the same starting point is the only thing that really matters.
To get the number of days between two numbers representing seconds from the same starting point:
days = (end_seconds - start_seconds)/60/60/24
or
SELECT (end_seconds - epic_start)/60/60/24 AS numdays
Redshift will return an integer value without the decimal portion, so if the formula returns 1.9, numdays will be 1.

You are passing wrong parameters in datediff().
SELECT DATEDIFF('2014-11-30','2014-11-29') AS DiffDate
Above will return the difference in days between two given dates.
Read more on datediff() here datediff

Related

Generating time series reports

I'm trying to work out how to create a solution that will allow me to query a table that has a timestamp, and in return get a time series data. The request consists of start/end date & time, granularity type (minute, hour, day, week, month and year) and granularity value. Having tried to use in a query something like
GROUP BY ROUND(UNIX_TIMESTAMP(created_at) DIV 60)
to get the results per one minute, or DIV 300 for every five minutes is fine. The problem lies further up for calculating months and years' seconds which will be inaccurate. I've stumbled upon the generate_series in PGSQL (MySQL alternative) and am stuck trying to tie them together. How do I calculate a count of rows, for example, for two days, on a 15 minute granularity? It's a complex question that I'll probably have to break down further.
I have already visited #1 and #2, but they are incomplete.
To me it seems that rounding will only be allowed to certain level and I'd have to restrict it (i.e .for 2 months period there cannot be hourly breakdown).
EDIT
It gave me the wrong impression - I would not have to calculate monthly figures based on seconds using the query like:
SELECT DATE_FORMAT(MIN(created_at),'%d/%m/%Y %H:%i:%s' as date,
COUNT(*) AS count FROM guests
GROUP BY ROUND(UNIX_TIMESTAMP(created_at) / 300)
It's only going to do grouping based on minimum value. But the question still stands - is the best approach really to go through the time period using granularity value and "slice" the data that way without loosing too much accuracy?
It seems that the only approach is to run sub-queries for a set of data (i.e. for a period of two months, generate 15 minute intervals timestamps, group the data into them and produce an aggregate) without dividing the original timestamp to produce the rounded approximation.
Let's say you have a gigantic table measure with two columns datestamp and temp.
Let's say you want to see the temperature every six minutes (10x per hour) for the last week. You can do this sort of thing. We'll get to defining trunc in a moment.
SELECT trunc(datestamp) datestamp, AVG(temp) temp
FROM measure
WHERE datestamp >= CURDATE() - INVERVAL 7 DAY
GROUP BY trunc(datestamp)
ORDER BY trunc(datestamp)
That works for any reasonable definition of trunc. In this case trunc(t) returns the beginning of the six-minute period in which t occurs. So, trunc('1942-12-07 08:45:17') gives 1942-12-07 08:42:00).
Here's a query that works for every six minute interval.
SELECT DATE_FORMAT(datestamp,'%Y-%m-%d %H:00') +
INTERVAL (MINUTE(datestamp) -
MINUTE(datestamp) MOD 6) datestamp,
AVG(temp) temp
FROM measure
WHERE datestamp >= CURDATE() - INVERVAL 7 DAY
GROUP BY DATE_FORMAT(datestamp,'%Y-%m-%d %H:00') +
INTERVAL (MINUTE(datestamp) -
MINUTE(datestamp) MOD 6)
ORDER BY 1
This uses inbuilt date arithmetic rather than unix timestamp arithmetic.
You can use a stored function to make this easier to read.
DELIMITER $$
DROP FUNCTION IF EXISTS TRUNC_N_MINUTES$$
CREATE
FUNCTION TRUNC_N_MINUTES(datestamp DATETIME, n INT)
RETURNS DATETIME DETERMINISTIC NO SQL
COMMENT 'truncate to N minute boundary. For example,
TRUNCATE_N_MINUTES(sometime, 15) gives the nearest
preceding quarter hour'
RETURN DATE_FORMAT(datestamp,'%Y-%m-%d %H:00') +
INTERVAL (MINUTE(datestamp) -
MINUTE(datestamp) MOD n) MINUTE$$
DELIMITER ;
Then your query will say
SELECT TRUNC_N_MINUTES(datestamp, 6) datestamp, AVG(temp) temp
FROM measure
WHERE datestamp >= CURDATE() - INVERVAL 7 DAY
GROUP BY TRUNC_N_MINUTES(datestamp, 6)
ORDER BY TRUNC_N_MINUTES(datestamp, 6)
If you want to summarize by 5, 10, 15, or minute boundaries (three items per hour) simply use that number in place of 6.
You'll need different trunc() functions for hours, etc.
The trunc() function for daily summaries is DATE(datestamp).
For monthly summaries it is LAST_DAY(datestamp). For example,
SELECT LAST_DAY(datestamp) month_ending, AVG(temp) temp
FROM measure
GROUP BY LAST_DAY(datestamp)
ORDER BY LAST_DAY(datestamp)
yields a month-by-month summary.

use group by in mysql to aggregate 5-minute timestamp intervals

I have a mySQL database called crypto where inside I have a table called coin with three different columns: timestamp, price, volume.
The problem is the following: I want to group the data by timestamp in a period of 5 minutes, where the field price presents the maximum value and the field volume presents the sum.
I tried the following command:
SELECT sum(volume), max(price),
round(unix_timestamp(addtime(date(0), timestamp) )/(15*60)) AS
timestamp
FROM btcusd_raw0
GROUP BY timestamp;
But it doesn't return the datetime as a column.
Think about this as truncating a datestamp expression to the next lowest five-minute boundary.
How can you do that? This (long) expression works:
DATE_FORMAT(datestamp,'%Y-%m-%d %H:00') +
INTERVAL (MINUTE(datestamp) - MINUTE(datestamp) MOD 5) MINUTE
How does it work?
DATE_FORMAT(datestamp,'%Y-%m-%d %H:00') gives the hour of the expression. For example, it turns 2001-09-11 08:42:00 into 2001-09-11 08:00:00 .
(MINUTE(datestamp) - MINUTE(datestamp) MOD 5) retrieves the minute (42 in the example) and turns it to the next lowest five-minute boundary 40.
hourvalue + INTERVAL minutevalue MINUTE adds the hour and minute together. 2001-09-11 08:40:00
So, use this expression in your query, both in the SELECT and GROUP BY clauses.
SELECT sum(volume), max(price),
DATE_FORMAT(timestamp,'%Y-%m-%d %H:00') +
INTERVAL (MINUTE(timestamp) - MINUTE(timestamp) MOD 5) MINUTE
FROM btcusd_raw0
GROUP BY DATE_FORMAT(timestamp,'%Y-%m-%d %H:00') +
INTERVAL (MINUTE(timestamp) - MINUTE(timestamp) MOD 5) MINUTE;
It makes for verbose queries. You might consider creating a stored function for it. Here's a more complete explanation.

Error Code: 1292. Truncated incorrect time value

SELECT *
FROM SESSIONS
WHERE TIME_TO_SEC(TIMEDIFF(NOW(), SESSION_CREATED)) / 3600 >= 24
This give me 2 results
DELETE FROM SESSIONS
WHERE TIME_TO_SEC(TIMEDIFF(NOW(), SESSION_CREATED)) / 3600 >= 24
And this give me: "Error Code: 1292. Truncated incorrect time value"
SESSION_CREATED is TIMESTAMP Datatype
Actual data:
SESSION_ID SESSION_CREATED
223133 2017-05-22 07:14:34
223134 2017-05-22 07:14:36
How can the select work but not the delete?
Why are you using such a complicated expression? Why not just do:
DELETE FROM SESSIONS
WHERE SESSION_CREATED < NOW() - INTERVAL 1 DAY;
As for why your code might fail, it is using timediff() which is limited to the range of the time data type. And this is:
MySQL retrieves and displays TIME values in 'HH:MM:SS' format (or
'HHH:MM:SS' format for large hours values). TIME values may range from
'-838:59:59' to '838:59:59'.
Because you are using NOW(), the values change from one iteration to the next. You just happened to run the SELECT when the data wasn't too old and then the DELETE when it was.
Example for Timediff using TIMESTAMPDIFF on MySQL:
To use TIMESTAMPDIFF, define the unit (SECOND, MINUTE, HOUR...), the initial and end date (must be timestamp's datatype).
ROUND( TIMESTAMPDIFF(HOUR, initial_date, CURRENT_TIMESTAMP()) / 24, 2 )

Select last 24 hours from SQlite where EPOCH time used

I am trying to select all data from an SQlite database for the last 24 hours. There is a column 'Date' where the date is present and that is in EPOCH time. I've tried a variety of different commands but this seems to be what I have so far:
SELECT *
FROM Log
WHERE UNIX_TIMESTAMP(DATE_ADD(NOW(),INTERVAL -1 DAY))
and
SELECT * FROM Log WHERE Date >= datetime('now', ' '-24 hours');
This doesn't seem to work. Ultimately, I am trying to convert the last 24 hours of this database to a CSV in Unix and have only the last 24 hours there using the following:
sqlite3 -header -csv /opt/demo/log_20170501131627.db " select * from Log
WHERE Date >= datetime('now', ' '-24 hours');" > /opt/demo/DB.csv
Any ideas?
SELECT * FROM Log WHERE Date >= strftime('%s', 'now', '-1 day');
You can try it here:
http://sqlfiddle.com/#!5/440d5/2/0
edit: simplified strftime usage based on "CL."-s comment below (thanks)
I'm not sure the precision of your epoch time. In case you are saving your epoch time to the millisecond, you can do it like this:
SELECT * FROM Log WHERE CAST((DATE/1000) AS LONG) >= strftime('%s', 'now', '-1 day');
The divide by 1000 above is just converting it to seconds and then casting it to a long (decimal values don't work if you are using '%s'). So if your epoch time is in seconds, just ignore the cast and division part of the above solution. Hope this helps!

Epoch Date Conversion to SQL Server

Good Day,
I have a question. What type of epoch date's are these and how would I convert them into a SQL Server datetime format.
37564691530
37564704499
37564708633
37564721033
37564743361
37564746236
I have googled for 2 days and cant find anything except this formula which gives me an arithmetic overflow message when i try to convert it.
select
DATEADD(ss, 37564691530 - 3600 * 5, CONVERT(DATETIME, '1900-01-01 00:00:00', 102))
Any help would really be appreciated.
13 digit epoch represent total milliseconds 10 digit epoch represent total seconds. You have first one - milliseconds.
And sql DateAdd function accept second parameter(Increment) as Integer. You try to pass a bigint value. Thats why throw Arithmetic overflow error.
try this
DECLARE #MS BIGINT
SET #MS = 37564746236
select DATEADD(SECOND, #MS / 1000, '1970-01-01')