How to find entry that is between two dates? - sql

I have a table as:
Id start_timestamp end_timestamp
1 2021-07-12 03:00:00 2021-07-13 11:58:05
2 2021-07-13 04:00:00 2021-07-13 05:00:00
3 2021-07-13 04:00:00 2021-07-13 09:00:00
4 2021-07-13 04:00:00 NULL
5 2020-04-10 04:00:00 2020-04-10 04:01:00
....
I want to find all records that fall between two specific timestamps? Basically I'm looking to understand what process ran during a high pick time of the day (it doesn't matter if they have 1 sec in the window or hours.. just occurrence in the window is enough)
So if the timestamps are 2021-07-13 00:00:00 to 2021-07-13 04:30:00
The query will return
1
2
3
4
How can I do that with SQL? (Preferably Presto)

This is the overlapping range problem. You may use:
SELECT *
FROM yourTable
WHERE
(end_timestamp > '2021-07-13 00:00:00' OR end_timestamp IS NULL) AND
(start_timestamp < '2021-07-13 04:30:00' OR start_timestamp IS NULL);
My answer assumes that a missing start/end timestamp value in the table logically means that this value should not be considered. This seems to be the logic you want here.

Related

How can i create a new column count in SQL table where count=1 if hours column >=6 else count=0

I aim to first achieve this
id
employee
Datelog
TimeIn
TimeOut
Hours
Count
5
Two
2022-08-10
09:00:00
16:00:00
07:00:00
1
4
Two
2022-08-09
09:00:00
16:00:00
07:00:00
1
3
Two
2022-08-08
09:00:00
16:00:00
07:00:00
1
2
One
2022-08-05
09:00:00
16:00:00
07:00:00
1
1
Two
2022-08-04
09:00:00
10:00:00
01:00:00
0
and now my main objective here is to give a bonus of 2k to employees whose Totalcount per month >=3.
employee
Month
TotalCount
Bonus
Two
August
3
2000
One
August
1
0
Here's the answer using Postgres. It's pretty much generic other than extracting the month out of datelog that might have a slightly different syntax.
select employee
,max(date_part('month', datelog ))
,count(*)
,case when count(*) >= 3 then 2000 else 0 end as bonus
from t
where hours >= time '06:00:00'
group by employee
employee
max
count
bonus
Two
8
3
2000
One
8
1
0
Fiddle

Getting available date intervals with overlapping busy times

I'm trying to get available date intervals from a predefined available dates and busy times.
Table of possible dates (slots)
ID
SLOT_BEG
SLOT_END
1
11/10/2021 09:00:00
11/10/2021 09:15:00
2
11/10/2021 09:15:00
11/10/2021 09:30:00
3
11/10/2021 09:30:00
11/10/2021 09:45:00
4
11/10/2021 09:45:00
11/10/2021 10:00:00
Busy times
ID
MEET_BEG
MEET_END
1
11/10/2021 09:00:00
11/10/2021 09:15:00
2
11/10/2021 09:32:24
11/10/2021 09:46:00
Desired result:
ID
SLOT_BEG
SLOT_END
2
11/10/2021 09:15:00
11/10/2021 09:30:00
db<>fiddle here
I'm unable to find a way to handle the overlapping cases like meet ID 2 - it needs to block 2 slots because the starting date is not aligned.
Any help is appreciated.
Use not exists with a subquery testing if the invervals do overlap
select * from T_TMP_SLOT s
where not exists (
select null from T_TMP_MEET m
where not (s.SLOT_END <= m.MEET_BEG or m.MEET_END <= s.SLOT_BEG)
);
ID SLOT_BEG SLOT_END
---------- ------------------- -------------------
2 11.10.2021 09:15:00 11.10.2021 09:30:00
Note that the intervals do not overlap if the slot end before (or equal) begin of meeting OR if the meeting ends before (or eq) slot begin.
So make a negation of this predicate to get overlapping meetings and check with not exists that such meetings do not exists..

Google Bigquery - Create time series of number of active records

I'm trying to create a timeseries in google bigquery SQL. My data is a series of time ranges covering the period of activity for that record. Here is an example:
Start End
2020-11-01 21:04:00 UTC 2020-11-02 07:15:00 UTC
2020-11-01 21:45:00 UTC 2020-11-02 04:00:00 UTC
2020-11-01 22:00:00 UTC 2020-11-02 09:48:00 UTC
2020-11-01 22:00:00 UTC 2020-11-02 06:00:00 UTC
I wish to create a new table to total the number of active records within a 15 minute block. "21:00:00" would for example be 21:00 to 21:14.59. My desired output for the above would be:
Period Active_Records
2020-11-01 21:00:00 1
2020-11-01 21:15:00 1
2020-11-01 21:30:00 1
2020-11-01 21:45:00 2
2020-11-01 22:00:00 4
2020-11-01 22:15:00 4
etc until the end of the last active range.
I would also like to be able to generate this on the fly by querying a date range and having it return every 15 minute block in the range and how many active records there was in that period.
Any assistance would be greatly appreciated.
Below is for BigQuery Standard SQL
#standardSQL
select ts as period, count(1) as Active_Records
from unnest((
select generate_timestamp_array(timestamp_trunc(min(start), hour), max(`end`), interval 15 minute)
from `project.dataset.table`
)) ts
join `project.dataset.table`
on not (`end` < ts or start > timestamp_add(ts, interval 15 * 60 - 1 second))
group by ts
if to apply to sample data from your question - output is

Multiplying a timestamp data for several times in BigQuery [duplicate]

This question already has answers here:
Is there a SQL function to expand table?
(4 answers)
Closed 3 years ago.
I have a time-series starting from 2017-01-01 00:00:00 to the end of 2017-12-31 23:00:00 for 1-hour interval. I need to duplicate this 1-year timestamp for 2400 times in the same column. I need help about this one..
Row Date_time
1 2017-01-01 00:00:00 UTC
2 2017-01-01 01:00:00 UTC
3 2017-01-01 02:00:00 UTC
4 2017-01-01 03:00:00 UTC
5 2017-01-01 04:00:00 UTC
6 2017-01-01 05:00:00 UTC
7 2017-01-01 06:00:00 UTC
8 2017-01-01 07:00:00 UTC
...........................
...........................
You would do this in BigQuery by generating a timestamp array and then unnesting:
select ts
from unnest(generate_timestamp_array('2017-01-01 00:00:00', '2017-12-31 23:00:00', interval 1 hour)) ts
You can then get multiple rows with a similar construct:
select ts
from unnest(generate_timestamp_array('2017-01-01 00:00:00', '2017-12-31 23:00:00', interval 1 hour)
) ts cross join
unnest(generate_series(1, 2400)) n

finding the data of time between 2 columns times

i have data like this
no_shift start_time end_time
1 08:00:01 15:00:00
2 15:00:01 20:00:00
3 20:00:01 03:00:00
4 03:00:01 08:00:00
i am using this syntax:
select * from shift_time where `20:15:22` between start_time and end_time
i got null.. but if i changed the value to
08:01:22 return 1
16:35:12 return 2
05:11:23 return 4
but if 22:02:22 i got null. how to solve this problem?