Time differences between 2 timestamps - sql

I want to find the ride_length/duration between started_at and ended_at in HH:MM:SS.
SELECT
ride_id,
started_at, --timestamp
ended_at, --timestamp
ended_at - started_at AS ride_length
FROM `case-study-1-bike-share-335613.bike_share.202102`
ORDER BY ride_length DESC
And this is what I get:
Am I calculating it the right way? I know there's a timestamp_diff function in SQL Big Query but it limited to only one type of measurement such as hours, minutes OR seconds. I want it in HH:MM:SS.
How do I remove 0-0 0 from the ride_length column? Why doesn't SQL Big Query convert the exceeding hours into day, or exceeding day into weeks?
Since ride_length is a measurement of time, I try SAFE_CAST((ended_at - started_at) AS time) but got an error instead:
Invalid cast from INTERVAL to TIME.
Should I just leave the column as it is? I can't have it convert to string because this table will imported to Tableau for visualization purposes. Thus it has to be some sort of numbers.

you can get the difference in seconds and convert for the format you need:
WITH table_a AS
(SELECT TIMESTAMP "2022-01-03 16:50:49 UTC" start_at, TIMESTAMP "2022-01-04 18:59:44 UTC" AS end_at)
SELECT start_at,
end_at,
regexp_replace(cast(time(diff) AS string),
r'^\d\d',
cast(extract(HOUR FROM time(diff)) + 24 * unix_date(date(diff)) AS string)) AS total_trip
FROM
(SELECT start_at,
end_at,
timestamp_seconds(DATETIME_DIFF(end_at, start_at, SECOND)) AS diff
FROM table_a)

Related

When to use DATE_TRUNC() vs. DATE_PART()?

I do not know when to use DATE_TRUNC and DATE_PART() in a query.
I have not really tried much, just some web searches that I do not fully grasp but I just started learning SQL (Postgres).
They both do very different things. One truncates a date to the precision specified (kind of like rounding, in a way) and the other just returns a particular part of a datetime.
From the documentation:
date_part():
The date_part function is modeled on the traditional Ingres equivalent
to the SQL-standard function extract:
date_part('field', source)
Note that here the field parameter needs to be a string value, not a
name. The valid field names for date_part are the same as for extract.
For historical reasons, the date_part function returns values of type
double precision. This can result in a loss of precision in certain
uses. Using extract is recommended instead.
SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');
Result: 16
SELECT date_part('hour', INTERVAL '4 hours 3 minutes');
Result: 4
date_trunct():
The function date_trunc is conceptually similar to the trunc function
for numbers.
date_trunc(field, source [, time_zone ]) source is a value expression
of type timestamp, timestamp with time zone, or interval. (Values of
type date and time are cast automatically to timestamp or interval,
respectively.) field selects to which precision to truncate the input
value. The return value is likewise of type timestamp, timestamp with
time zone, or interval, and it has all fields that are less
significant than the selected one set to zero (or one, for day and
month).
...
Examples (assuming the local time zone is America/New_York):
SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
Result: 2001-02-16 20:00:00
SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
Result: 2001-01-01 00:00:00
SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00');
Result: 2001-02-16 00:00:00-05
SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00', 'Australia/Sydney');
Result: 2001-02-16 08:00:00-05
SELECT date_trunc('hour', INTERVAL '3 days 02:47:33');
Result: 3 days 02:00:00

Changing Schema in GBQ

I manually created a duration field in excel which calculates a time duration between a start date and end date and formatted it as HH:MM:SS. When I upload this in Google Big query it appears as a string. Then I used a CAST function
SELECT CAST (ride_length AS INTERVAL)
to change the type from STRING to INTERVAL and got the following error
Invalid INTERVAL value '0.00:22:28'
I need to change the data type to a number so I can calculate maximum, minimum, and average duration. GBQ doesn't let me do that with a string data type.
SELECT CAST (ride_length AS INTERVAL)
Can you try below:
WITH
sampleData AS(
SELECT
'01:05:07' AS duration
UNION ALL
SELECT
'02:05:07' AS duration
UNION ALL
SELECT
'04:05:07' AS duration ),
sample AS (
SELECT
CAST(duration AS TIME FORMAT 'HH24:MI:SS') AS duration2
FROM
sampleData --converts string to time format
)
SELECT
MAX(duration2) AS MAXTIME,
MIN(duration2) AS MINTIME,
TIME(
EXTRACT(hour FROM AVG(duration2 - '0:0:0')),
EXTRACT(minute FROM AVG(duration2 - '0:0:0')),
EXTRACT(second FROM AVG(duration2 - '0:0:0'))
) as AVERAGE from
sample;
This is given that your sample's format are accepted by BigQuery, See the sample output below for getting Max, Min, Average:
UPDATE:
Additional Code (for better readability, just change the names appropriate to your table ):
WITH sample AS (
SELECT
CAST(yourfieldName AS TIME FORMAT 'HH24:MI:SS') AS duration
FROM
yourTableId --converts string to time format
)
SELECT
MAX(duration) AS MAXTIME,
MIN(duration) AS MINTIME,
TIME(
EXTRACT(hour FROM AVG(duration - '0:0:0')),
EXTRACT(minute FROM AVG(duration - '0:0:0')),
EXTRACT(second FROM AVG(duration - '0:0:0'))
) as AVERAGE from
sample;

How to substract 2 varchar dates in oracle?

I have these varchar : 20211026231735.
So I would like a query to substract actual sysdate to that date and convert the substraction to DAY HOURS AND SECONDS.
select TO_CHAR(SYSDATE,'YYYYMMDDHH24MISS') - start_time from TABLEA where job_name='jOB_AA_BB';
I get 4220.
Any help please? Thanks
When you do datetime arithmetic with the DATE datatype, you get back a NUMBER of days. To get an INTERVAL you can subtract two TIMESTAMPs. You don't say what the data type is for start_time, but you might get away with this:
select localtimestamp - start_time
from tablea where job_name='jOB_AA_BB';
LOCALTIMESTAMP gives you a TIMESTAMP value in the current session time zone. There's also CURRENT_TIMESTAMP, which give you the same thing in a TIMESTAMP WITH TIME ZONE and SYSTIMESTAMP that gives you the database time in TIMESTAMP WITH TIME ZONE. You may need to convert your start_time to avoid time zone differences, if any.
You can us the function numtodsinterval to convert the results of date arithmetic to an interval. If necessary then use extract to pull out the needed components.
with tablea(job_name, start_time) as
(select 'jOB_AA_BB','20211026231735' from dual)
select numtodsinterval((SYSDATE - to_date( start_time,'yyyymmddhh24miss')),'hour') date_diff
from tablea where job_name='jOB_AA_BB' ;
with tablea(job_name, start_time) as
(select 'jOB_AA_BB','20211026231735' from dual)
select extract (hour from date_diff) || ':' || extract (minute from date_diff)
from (
select numtodsinterval((sysdate - to_date( start_time,'yyyymmddhh24miss')),'day') date_diff
from tablea where job_name='jOB_AA_BB'
);
NOTE: I am not sure how you got any result, other than an error, as your query winds up as a string - a string. You should not convert sysdate to a string but your string to a date (better yet store it as the proper data type - date).
You can convert the value to a date (rather than converting SYSDATE to a string) and then subtract and explicitly return the value as an INTERVAL DAY TO SECOND type:
SELECT (SYSDATE - TO_DATE('20211026231735', 'YYYYMMDDHH24MISS')) DAY TO SECOND
FROM DUAL;
Or, for your table:
SELECT (SYSDATE - TO_DATE(start_time,'YYYYMMDDHH24MISS')) DAY(5) TO SECOND
FROM TABLEA
WHERE job_name='jOB_AA_BB';
db<>fiddle here

How can I extract just the hour of a timestamp using standardSQL

How can I extract just the hour of a timestamp using standardSQL.
I've tried everything and no function works. The problem is that I have to extract the time from a column and this column is in the following format:2018-07-09T02:40:23.652Z
If I just put the date, it works, but if I put the column it gives the error below:
Syntax error: Expected ")" but got identifier "searchIntention" at [4:32]
Follow the query below:
#standardSQL
select TOTAL, dia, hora FROM
(SELECT cast(replace(replace(searchIntention.createdDate,'T',' '),'Z','')as
DateTime) AS DIA,
FORMAT_DATETIME("%k", DATETIME searchIntention.createdDate) as HORA,
count(searchintention.id) as Total
from `searchs.searchs2016626`
GROUP BY DIA)
Please, help me. :(
How can I extract just the hour of a timestamp using standardSQL?
Below is for BigQuery Standard SQL
You can use EXTRACT(HOUR FROM yourTimeStampColumn)
for example:
SELECT EXTRACT(HOUR FROM CURRENT_TIMESTAMP())
or
SELECT EXTRACT(HOUR FROM TIMESTAMP '2018-07-09T02:40:23.652Z')
or
SELECT EXTRACT(HOUR FROM TIMESTAMP('2018-07-09T02:40:23.652Z'))
In BigQuery Standard SQL, you can use the EXTRACT timestamp function in order to return an INT64 value corresponding to the part of the timestamp that you want to retrieve, like.
The available parts includes a full list that you can check in the documentation page linked, but in your use case you can directly refer to the HOUR operator in order to retrieve the INT64 representation of the hour value in a field of TIMESTAMP type.
#standardSQL
# Create a table
WITH table AS (
SELECT TIMESTAMP("2018-07-09T02:40:23.652Z") time
)
# Extract values from a Timestamp expression
SELECT
EXTRACT(DAY FROM time) as day,
EXTRACT(MONTH FROM time) as month,
EXTRACT(YEAR FROM time) as year,
EXTRACT(HOUR FROM time) AS hour,
EXTRACT(MINUTE FROM time) as minute,
EXTRACT(SECOND from time) as second
FROM
table

How to get the date and time from timestamp in PostgreSQL select query?

How to get the date and time only up to minutes, not seconds, from timestamp in PostgreSQL. I need date as well as time.
For example:
2000-12-16 12:21:13-05
From this I need
2000-12-16 12:21 (no seconds and milliseconds only date and time in hours and minutes)
From a timestamp with time zone field, say update_time, how do I get date as well as time like above using PostgreSQL select query.
Please help me.
There are plenty of date-time functions available with postgresql:
See the list here
http://www.postgresql.org/docs/9.1/static/functions-datetime.html
e.g.
SELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 16
For formatting you can use these:
http://www.postgresql.org/docs/9.1/static/functions-formatting.html
e.g.
select to_char(current_timestamp, 'YYYY-MM-DD HH24:MI') ...
To get the date from a timestamp (or timestamptz) a simple cast is fastest:
SELECT now()::date
You get the date according to your local time zone either way.
If you want text in a certain format, go with to_char() like #davek provided.
If you want to truncate (round down) the value of a timestamp to a unit of time, use date_trunc():
SELECT date_trunc('minute', now());
This should be enough:
select now()::date, now()::time
, pg_typeof(now()), pg_typeof(now()::date), pg_typeof(now()::time)