I am generating one time-series from using below query.
SELECT date_trunc('min', dd):: TIMESTAMP WITHOUT TIME zone as time_ent
FROM generate_series ( timestamp '2021-12-09 06:34:37' + ((DATE_PART('min', timestamp '2021-12-09 06:34:37')::integer % 2) || ' minutes') :: INTERVAL
, '2021-12-10 06:34:37'::timestamp
, '20 min'::interval) dd
and it will give me output like below.
2021-12-09 06:34:00.000
2021-12-09 06:54:00.000
2021-12-09 07:14:00.000
2021-12-09 07:34:00.000
but I need output like.
2021-12-09 06:40:00.000
2021-12-09 07:00:00.000
2021-12-09 07:20:00.000
2021-12-09 07:40:00.000
currently, the time series hours depend upon the timestamp that I pass. in above it gives me mins like 34,54,14...but I want the mins like 40,00,20...it should not depend on the time I passed in query. I tried with timestamp '2021-12-09 06:34:37' + ((DATE_PART('min', timestamp '2021-12-09 06:34:37')::integer % 2) || ' minutes') :: INTERVAL but not any success.
Based on your description, I assumed that you want to create a series of timestamps for 00, 20, 40 minute at each hour until the next day.
select *
from (
select date_trunc('hour', current_timestamp) + i * interval '20 minutes' as ts
from generate_series(1, 24*3) as t(i)) t
where ts between current_timestamp and current_timestamp + interval '1 day'
The key idea here is to truncate the current_timestamp to 00 minute first. This becomes the start of the series. Then filter out the generated timestamps outside the range you want. You may need to adjust the second argument of generate_series function, depending on your requirement.
Or you can just generate a series of timestamp like the following:
select *
from (
select ts
from generate_series(
date_trunc('hour', current_timestamp),
current_timestamp + interval '1 day',
interval '20 minutes') as t(ts)) as t
where ts between current_timestamp and current_timestamp + interval '1 day'
Here, you still need to trunc your timestamp to hour first so the start of the series at 00 minute.
Related
Please tell me if it is somehow easier to write this query where the check occurs at intervals?
SELECT type, time_from, time_to
FROM manager_orders
WHERE aptid = 262707
AND cancelled_at is null
AND ('2021-04-26 11:00:00'
BETWEEN time_from - INTERVAL 30 Minute
AND time_to + INTERVAL 30 Minute
OR '2021-04-26 11:00:00'
BETWEEN time_from - INTERVAL 30 Minute
AND time_to + INTERVAL 60 Minute
)
I have rainfall measurements stored in a postgresql table and wish to select the min and and max value since the last occurence of 9am, whether that is 9am of the current day, if after 9am, or 9am of the previous day if before 9am. Have managed to select the values I need for the current day like so:
"select max(rain_mm) as maxrain,min(rain_mm) as minrain from weatherstation_000 where time_stamp > date_trunc('day',now());" But now want a simple way to do min and max rainfall since 9am as well, whether that be through the use of a conditional expression or perhaps a change of timezone??
You can use the OR condition as follows based of now().
select max(rain_mm) as maxrain,
min(rain_mm) as minrain
from weatherstation_000
where (now() > date_trunc('day', now()) + interval '9 hour'
and time_stamp > date_trunc('day', now()) + interval '9 hour')
OR ((now() <= date_trunc('day', now()) + interval '9 hour'
and time_stamp > date_trunc('day', now()) - interval '15 hour'))
You can subtract 9 hours:
select max(rain_mm) as maxrain,min(rain_mm) as minrain
from weatherstation_000
where time_stamp > date_trunc('day', now() - interval '9 hour');
I need to know how many entries appear in my DB for the past 7 days with a timestamp between 23:00 & 01:00...
The Issue I have is the timestamp goes across 2 days and unsure if this is even possible in the one query.
So far I have come up with the below:
select trunc(timestamp) as DTE, extract(hour from timestamp) as HR, count(COLUMN) as Total
from TABLE
where trunc(timestamp) >= '12-NOV-19' and
extract(hour from timestamp) in ('23','00','01')
group by trunc(timestamp), extract(hour from timestamp)
order by 1,2 desc;
The result I am hoping for is something like this:
DTE | Total
20-NOV-19 5
19-NOV-19 4
18-NOV-19 4
17-NOV-19 6
Many thanks
Filter on the day first comparing it to TRUNC( SYSDATE ) - INTERVAL '7' DAY and then consider the hours by comparing the timestamp to itself truncated back to midnight with an offset of a number of hours.
select trunc(timestamp) as DTE,
extract(hour from timestamp) as HR,
count(COLUMN) as Total
from TABLE
WHERE timestamp >= TRUNC( SYSDATE ) - INTERVAL '7' DAY
AND ( timestamp <= TRUNC( timestamp ) + INTERVAL '01:00' HOUR TO MINUTE
OR timestamp >= TRUNC( timestamp ) + INTERVAL '23:00' HOUR TO MINUTE
)
group by trunc(timestamp), extract(hour from timestamp)
order by DTE, HR desc;
Subtract or add an hour to derive the date. I'm not sure what date you want to assign to each period, but the idea is:
select trunc(timestamp - interval '1' hour) as DTE,
count(*) as Total
from t
where trunc(timestamp - interval '1' hour) >= DATE '2019-11-12' and
extract(hour from timestamp) in (23, 0)
group by trunc(timestamp - interval '1' hour)
order by 1 desc;
Note: If you want times between 11:00 p.m. and 1:00 a.m., then you want the hour to be 23 or 0.
In BIRT Report (which executes query for 10 minutes automatically - 24x7), I would like to report data of datatype "Timestamp", which I import from a table in oracle databank using query. Let's say I have a table with name "table 1". Table 1 contains a column with name "column1" of datatype timestamp. The data in column1 is from a machine which runs continuously (24x7 - 365 days).
Everyday in the report, I would like to present only 24 hours data, which is between 05:30:00 (present day) and 05:30:00 (next day).
SELECT column1 from table 1
WHERE coulmn1 = SYSDATE - INTERVAL '24' hour;
Extracting data of last 24 hours or days or months is easy, but how to define a logic in where statement, which takes the actual systemtime as a reference and provides data between 05:30 (present day) and 05:30 (next day).
For Example:
The automatic execution of query at 01:00:00 (or 1 AM) should show the data from previous day (05:30:00) to present (01:00:00)
The automatic executin of query at 08:00:00 (or 8 AM) should show the data from actual day (05:30:00 to 08:00:00).
Any help how to define a logic in where statement will be appreciated.
Use TRUNC(SYSDATE) to trunate it back to midnight and then add an INTERVAL:
SELECT column1
FROM table1
WHERE column1 >= TRUNC( SYSDATE ) + INTERVAL '0 05:30' DAY TO MINUTE
AND column1 < TRUNC( SYSDATE ) + INTERVAL '1 05:30' DAY TO MINUTE;
If you want to handle the case when the SYSDATE is before 05:30 then:
SELECT column1
FROM table1
WHERE column1 >= TRUNC( SYSDATE - INTERVAL '05:30' HOUR TO MINUTE )
+ INTERVAL '0 05:30' DAY TO MINUTE
AND column1 < TRUNC( SYSDATE - INTERVAL '05:30' HOUR TO MINUTE )
+ INTERVAL '1 05:30' DAY TO MINUTE;
And if you do not want to show future times then:
SELECT column1
FROM table1
WHERE column1 >= TRUNC( SYSDATE - INTERVAL '05:30' HOUR TO MINUTE )
+ INTERVAL '0 05:30' DAY TO MINUTE
AND column1 <= SYSTIMESTAMP;
I have the following table:
id | time
----+-------------
1 | 21:00:00+01
2 | 22:00:00+01
3 | 23:00:00+01
Column id is of type integer and time is time with timezone. I want to select all rows that fall within a specified interval, e.g.,
select *
from times
where time >= time '22:30' - interval '60 minutes' and time <= time '22:30' + interval '60 minutes';
However, if the intervall extends past midnight, i.e., when I select 23:30 as time argument, then I get an empty result set.
Is there a way to tell postgress to ignore the minutes that span past midnight?
You can use this logic:
select *
from times t cross join
(values ('22:30'::time - interval '60 minutes', '22:30'::time + interval '60 minutes')
) v(fromt, tot)
where (fromt <= tot and time >= fromt and time <= tot) or
(fromt > tot and (time >= fromt or time <= tot))