How to check overlap date time with specific time SQL - sql

I using postgresSql and i want check overlap date in specific datetime, not range date time.
Example :
I have booking room two time and it booking every saturday :
StartTime EndTime
2019-08-10 00:00:00 2019-08-20 03:00:00
I only want check datetime every saturday(startTime + 7 days) every week. If I put time look like :
StartTime EndTime
2019-08-17 00:00:00 2019-08-17 03:00:00
it overlaps . If i put time :
StartTime EndTime
2019-08-16 00:00:00 2019-08-16 03:00:00
it not overlaps.
If i using command sql look like :
SELECT (TIMESTAMP '2019-08-10 00:00:00', TIMESTAMP '2019-08-10 03:00:00') OVERLAPS (TIMESTAMP '2019-08-10 01:00:00',TIMESTAMP '2019-08-20 01:00:00')
It check all date in range time: 2019-08-10 -> 2019-08-20 and throw overlaps . I only want check 2019-08-10 an 2019-08-17 and throw overlaps. If date 2019-08-11,2019-08-12,2019-08-13,2019-08-14,2019-08-15,2019-08-16,2019-08-18,2019-08-19,2019-08-20 it not overlaps. How to do that.
It same question it monthly. Please help ?

You may add an additional condition If at least one Saturday falls in the given range
SELECT
(TIMESTAMP '2019-08-10 00:00:00', TIMESTAMP '2019-08-10 03:00:00')
OVERLAPS
(TIMESTAMP '2019-08-10 01:00:00', TIMESTAMP '2019-08-20 01:00:00') AND
EXISTS (
select 1 from generate_series(
TIMESTAMP '2019-08-10 00:00:00',
TIMESTAMP '2019-08-10 03:00:00',
INTERVAL '1 DAY'
) as dt where extract(isodow from dt ) = 6
) --ISO day of the week

Related

Need to create a 5 minute interval in trino for a date and show an aggregate function

data table format
timestamp
stream_id
2021-01-01 12:30:29.928
123.
2021-01-01 01:30:29.928
124.
2021-01-01 05:30:29.928
223.
2021-01-01 01:23:29.928
134.
expected output
day
timestamp.
count(stream_id)
2021-01-01.
12:00.
5.
2021-01-01.
12:05.
18
2021-01-01.
12:10.
39
2021-01-01.
12:20.
90
2021-01-01.
12:25.
45
2021-01-01.
12:30.
76
2021-01-01.
12:35.
93
You can use some date manipulation to split timestamp into parts and then use them to group data and perform aggregation:
-- sample data
WITH dataset(timestamp, stream_id) AS (
values (timestamp '2021-01-01 12:30:29.928', 123),
(timestamp '2021-01-01 01:30:29.928', 124),
(timestamp '2021-01-01 05:30:29.928', 223),
(timestamp '2021-01-01 01:23:29.928', 134),
(timestamp '2021-01-01 01:24:29.928', 135),
(timestamp '2021-01-01 01:26:29.928', 136)
)
-- query
select day,
date_add('minute', 5*grp, day) ts, -- construct the 5 minute group back
count(*) cnt
from
(select date_trunc('day', timestamp) day,
date_diff('millisecond', date_trunc('day', timestamp), timestamp) / (5 * 60 * 1000) grp,
stream_id
from dataset)
group by day, grp;
Output:
day
ts
cnt
2021-01-01 00:00:00.000
2021-01-01 12:30:00.000
1
2021-01-01 00:00:00.000
2021-01-01 01:25:00.000
1
2021-01-01 00:00:00.000
2021-01-01 05:30:00.000
1
2021-01-01 00:00:00.000
2021-01-01 01:30:00.000
1
2021-01-01 00:00:00.000
2021-01-01 01:20:00.000
2
Use date_format if needed to turn timestamps into needed representations.

bigquery creating timestamp buckets with 15 minutes interval

I want to achieve this:
Output
12:00:00 - 12:15:00
12:15:00 - 12:30:00
12:30:00 - 12:45:00
12:45:00 - 1:00:00 .......,
count(orders)
from table
I have a timestamp in the data table available (2022-07-05 19:45:00 UTC), I want to achieve #orders with every 15 minutes interval for a day.
Using RANGE_BUCKET function, you can create timestamp buckets for each 15 minutes. Consider below sample query:
https://cloud.google.com/bigquery/docs/reference/standard-sql/mathematical_functions#range_bucket
CREATE TEMP TABLE sample_table AS
SELECT * FROM UNNEST(GENERATE_TIMESTAMP_ARRAY('2022-07-05 00:00:00', '2022-07-05 10:00:00', INTERVAL 3 MINUTE)) `order`
;
SELECT TIMESTAMP_SECONDS(intervals[SAFE_OFFSET(RANGE_BUCKET(UNIX_SECONDS(`order`), intervals) - 1)]) ts,
COUNT(`order`) AS orders,
FROM `sample_table`,
UNNEST ([STRUCT(GENERATE_ARRAY(UNIX_SECONDS('2022-07-05'), UNIX_SECONDS('2022-07-06'), 60 * 15) AS intervals)])
GROUP BY 1
ORDER BY 1

how to use Current Timestamp in SQL query (Oracle)

I would like to run the query to show the data before 30 days and after 30 days, I know i should use CURRENT TIMESTAMP to do this and I'm able to run data before 30 days but not after 30 days. Below is my query and kindly advise this situation. Thanks!
COB.COB_FA > CURRENT TIMESTAMP - 30 days and COB.COB_FA > CURRENT TIMESTAMP + 30 days
I think you simply want or:
COB.COB_FA < CURRENT TIMESTAMP - interval '30' day or
COB.COB_FA > CURRENT TIMESTAMP + '30' day
Try below with current_timestamp (+/-) interval '30' day
COB.COB_FA < current_timestamp - interval '30' day or COB.COB_FA > current_timestamp + interval '30' day
sysdate can do this.
`COB.COB_FA between sysdate - 30 and sysdate + 30
this will work:
create table table_date(dd date);
insert into table_date values(trunc(sysdate));
insert into table_date values(trunc(sysdate)+1);
insert into table_date values(trunc(sysdate)+2);
insert into table_date values(trunc(sysdate)+9);
insert into table_date values(add_months(trunc(sysdate),-5));
//inserting more of them
alter session set nls_date_format = 'dd/MON/yyyy hh24:mi:ss';
SELECT * FROM table_date order by dd;
11/MAY/2018 00:00:00
11/JUL/2018 00:00:00
11/OCT/2018 00:00:00
12/OCT/2018 00:00:00
13/OCT/2018 00:00:00
18/OCT/2018 00:00:00
20/OCT/2018 00:00:00
11/JAN/2019 00:00:00
11/MAR/2019 00:00:00
SELECT * FROM table_date where dd>add_months(current_timestamp,1) or
dd<add_months(current_timestamp,-1);
sample output:
11/JAN/2019 00:00:00
11/MAR/2019 00:00:00
11/JUL/2018 00:00:00
11/MAY/2018 00:00:00

Add 8AM UTC to a date in oracle

I have a date something like below :
Thu Nov 29 18:00:00 CST 2018
Thu Apr 26 01:00:00 BST 2018
I need to convert it to 8AM UTC in oracle.
How do i do this ?
It is a string not date.
Referred link deals with proper dates and there is no accepted answer for it.
Thanks in Advance
Since it's a string you could use regexp_replace.
regexp_replace(nmuloc, '[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2} [A-Z]{3}', '08:00:00 GMT')
Oracle Setup
CREATE TABLE table_name ( datetime TIMESTAMP WITH TIME ZONE );
INSERT INTO table_name
SELECT TIMESTAMP '2018-11-29 18:00:00 CST' FROM DUAL UNION ALL
SELECT TIMESTAMP '2018-04-26 01:00:00 Europe/London' FROM DUAL UNION ALL
SELECT TIMESTAMP '2018-06-26 00:00:00 Europe/London' FROM DUAL;
Query 1:
Use datetime AS TIME ZONE 'UTC' to convert it from your time zone to UTC
Then use TRUNC() to truncate it back to the start of the UTC day (and also cast it to a date)
Because its now a date, use CAST( ... AS TIMESTAMP ) to get it back to a timestamp
Then use FROM_TZ( ..., 'UTC' ) to get it to be a timestamp in the UTC time zone
Then add INTERVAL '8' HOUR to be 8am.
Like this:
SELECT FROM_TZ(
CAST(
TRUNC( datetime AT TIME ZONE 'UTC' )
AS TIMESTAMP
),
'UTC'
) + INTERVAL '8' HOUR AS utc_date_at_8am_utc
FROM table_name;
Output:
UTC_DATE_AT_8AM_UTC
--------------------------------
30-NOV-18 08.00.00.000000 AM UTC
26-APR-18 08.00.00.000000 AM UTC
25-JUN-18 08.00.00.000000 AM UTC
Note: this translates 2018-06-26 00:00:00 BST to 2018-06-25 23:00:00 UTC before truncating. So it will be the same UTC day (but not necessarily the same day in the local time zone).
Query 2
If this is an issue then just remove the initial time zone conversion:
SELECT FROM_TZ(
CAST(
TRUNC( datetime )
AS TIMESTAMP
),
'UTC'
) + INTERVAL '8' HOUR AS date_at_8am_utc
FROM table_name
Output:
DATE_AT_8AM_UTC
--------------------------------
29-NOV-18 08.00.00.000000 AM UTC
26-APR-18 08.00.00.000000 AM UTC
26-JUN-18 08.00.00.000000 AM UTC

PostgreSQL time range duration over time series with default end if null

I need to be able to calculate the duration (in seconds) between two time stamps as an aggregate over a time series using a default end_datetime if it is null.
Imagine you have something like a punch card when you puch in and out:
username, start_datetime, end_datetime
What I want is a generated time series of the last N minutes with the duration for all users that overlap within that time frame. So it would be the SUM(end_datetime - start_datetime) where you would COALESCE a default end_datetime if it is null.
So the basic pieces I think I need are:
Generate the time interval:
select TIMESTAMP '2013-01-01 12:01:00' - (interval '1' minute * generate_series(0,5)) as timestamps;
COALESCE a default end_datetime
COALESCE(end_datetime, NOW())
Figure out the seconds difference between the start and end dates
So if one user logged in at 11:56:50 and it is now 12:01:40 we should get a table like:
timestamps duration
-------------------------------------
2013-01-01 12:01:00 40
2013-01-01 12:00:00 60
2013-01-01 11:59:00 60
2013-01-01 11:58:00 60
2013-01-01 11:57:00 60
2013-01-01 11:56:00 10
with t as (select '2013-01-01 11:56:50'::timestamp startt, '2013-01-01 12:01:40'::timestamp endt)
select
timestamps,
extract(epoch from
case
when timestamps=date_trunc('minute',startt) then date_trunc('minute',startt) + interval '1 minute' - startt
when timestamps =date_trunc('minute',endt) then endt- date_trunc('minute',endt)
else interval '60 seconds' end) as durations
from
(select generate_series(date_trunc('minute',startt),date_trunc('minute',endt),'1 minute') timestamps, * from t) a
order by
timestamps desc;
2013-01-01 12:01:00;40
2013-01-01 12:00:00;60
2013-01-01 11:59:00;60
2013-01-01 11:58:00;60
2013-01-01 11:57:00;60
2013-01-01 11:56:00;10
If you have multiple rows with start and end timestamp than the following will work:
select
id,
timestamps,
extract(epoch from
case
when timestamps=date_trunc('minute',startt) then date_trunc('minute',startt) + interval '1 minute' - startt
when timestamps =date_trunc('minute',endt) then endt- date_trunc('minute',endt)
else interval '60 seconds' end) as durations
from
(
select
id,
generate_series(date_trunc('minute',startt) ,
coalesce(date_trunc('minute',endt),date_trunc('minute',Now())),'1 minute') as timestamps,
startt, endt
from test
) a
order by
id, timestamps desc
SQLFiddle