Trouble pulling daily data - day resets at 5 PM - sql

I am trying to pull daily data using PostgreSQL. My problem is that the day seems to 'reset' at around 5 PM (Los Angeles Time). Is there a workaround this problem? Here is my query:
SELECT COUNT(distinct be.booking_id)AS "Number of Bookings Today"
FROM booking_events be
WHERE be.event IN ('approve') AND
be.created_at >= current_date AND
be.created_at < current_date + interval '1 day';

You can use hours to offset the current date. I think the logic is:
SELECT COUNT(distinct be.booking_id) as "Number of Bookings Today"
FROM booking_events be
WHERE be.event IN ('approve') AND
be.created_at >= current_date - interval '7 hour' AND
be.created_at < current_date + interval '1 day' - interval '7 hour';

Related

Combine multiple selects for statistics generation into on result set

Hey Pros,
I am far away to have good knowledge about SQL, and would ask you to give me some hints.
Currently we aggregate our data with python and I would try to switch this when possible to. (SQL (Postgresql server)
My goal is to have one statment that generate an average for two seperates column's for specific time intervals (1 Hour, 1 Day, 1 Week, Overall) also all events in each period shoud be counted.
I can create 4 single statments for each interval but strugle how to combine this four selects into on result set.
select
count(id) as hour_count,
camera_name,
round(avg("pconf")) as hour_p_conf,
round(avg("dconf")) as hour_d_conf
from camera_events where timestamp between NOW() - interval '1 HOUR' and NOW() group by camera_name;
select
count(id) as day_count,
camera_name,
round(avg("pconf")) as day_p_conf,
round(avg("dconf")) as day_d_conf
from camera_events where timestamp between NOW() - interval '1 DAY' and NOW() group by camera_name;
select
count(id) as week_count,
camera_name,
round(avg("pconf")) as week_p_conf,
round(avg("dconf")) as week_d_conf
from camera_events where timestamp between NOW() - interval '1 WEEK' and NOW() group by camera_name;
select
count(id) as overall_count,
camera_name,
round(avg("pconf")) as overall_p_conf,
round(avg("dconf")) as overall_d_conf
from camera_events group by camera_name;
When possbile the result should look like the data on image
Some hints would be great, thank u
Consider conditional aggregation by moving WHERE logic to CASE statements in SELECT. Alternatively, in PostgreSQL use FILTER clauses.
select
camera_name,
count(id) filter(timestamp between NOW() - interval '1 HOUR' and NOW()) as hour_count,
round(avg("pconf") filter(timestamp between NOW() - interval '1 HOUR' and NOW())) as hour_p_conf,
round(avg("dconf") filter(timestamp between NOW() - interval '1 HOUR' and NOW())) as hour_d_conf,
count(id) filter(timestamp between NOW() - interval '1 DAY' and NOW()) as day_count,
round(avg("pconf") filter(timestamp between NOW() - interval '1 DAY' and NOW())) as day_p_conf,
round(avg("dconf") filter(timestamp between NOW() - interval '1 DAY' and NOW())) as day_d_conf,
count(id) filter(timestamp between NOW() - interval '1 WEEK' and NOW()) as week_count,
round(avg("pconf") filter(timestamp between NOW() - interval '1 WEEK' and NOW())) as week_p_conf,
round(avg("dconf") filter(timestamp between NOW() - interval '1 WEEK' and NOW())) as week_d_conf,
count(id) as overall_count,
round(avg("pconf")) as overall_p_conf,
round(avg("dconf")) as overall_d_conf
from camera_events
group by camera_name;
The simplest way is to join them. For example:
select
coalesce(h.camera_name, d.camera_name, w.camera_name) as camera_name
h.hour_count, h.hour_p_conf, h.hour_d_conf
d.day_count, d.day_p_conf, d.day_d_conf
w.week_count, w.week_p_conf, w.week_d_conf
from (
-- hourly query here
) h
full join (
-- daily query here
) d on d.camera_name = h.camera_name
full join (
-- weekly query here
) w on w.camera_name = coalesce(h.camera_name, d.camera_name)

Postgres - how to displays data for the previous year?

I have sql
select
name,
tanggal,
status
from
tbl_person
where
status = 'PROSES'
and date_part('year', tanggal) = 2021 - INTERVAL '1 YEAR'
tanggal is date 2021-01-01
I want to display previous year's data for example in 2020, how to write the correct query?
Using your method:
where status = 'PROSES' and
date_trunc('year', tanggal) = date_trunc('year', current_date) - interval '1 year'
However, I prefer to avoid functions on the column -- so the query is easier to optimize. So I would recommend:
where status = 'PROSES' and
tanggal < date_trunc('year', now()) and
tanggal >= date_trunc('year', now()) - interval '1 year'
This just uses now() rather than current_date because it is easier to type.

Obtaining summary result since last occurence of specifc hour of day in postgresql

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');

SQL Query to get records from last week of every month for 4 years

I have below table
ABC Date
200 2019-02-22
-200 2019-02-23
1200 2019-02-24
-500 2019-02-25
'
'
'
'
-889 2015-01-11
I need to get values for from ABC for every day of last week of every month
select ABC
from table 1
where date between '2019-03-26' and '2019-03-30'
this is for month of march 2019. How do i create a loop such that it displays value for everyday of last week of every month for 3 years
You can use date arithmetic to get the last week of each month. In Terdata, I think this is one solution:
select abc
from table1
where (date >= (current_date - extract(day from date) * interval '1 day') - interval '6 day' and
date <= current_date - extract(day from date) * interval '1 day'
) or
(date >= (current_date - extract(day from date) * interval '1 day') - interval '1 month' - interval '6 day' and
date <= current_date - extract(day from date) * interval '1 day' - interval '1 month'
) or
(date >= (current_date - extract(day from date) * interval '1 day') - interval '2 month' - interval '6 day' and
date <= current_date - extract(day from date) * interval '1 day' - interval '12month'
);
SELECT ABC, DATE FROM table_1 WHERE DATEPART(wk, DATE) =
DATEPART(wk, EOMONTH(DATE)) AND DATE <= DATEADD(year,3,GETDATE())
DATEPART(wk, DATE) gives me the week number of that date, DATEPART(wk,EOMONTH(DATE)) gives me the week number of (the last day of the corresponding date's month). So, when I check this, I will only select dates belonging to the last week of every month. The next filter is to select only those dates which are lesser than 3 years from now (GETDATE()).

PostgreSQL querying the current week's data

I'm trying to grab all the appointments that have been booked for this current week I initially tried this:
select *
from appointments
where staff_id = 'id'
and (to_timestamp(appointments.start_time)) > (current_date - interval '1 week')
and (to_timestamp(appointments.start_time)) < (current_date + interval '1 week')
This just selects all the appointments that equal +/- 7 days, so not the current week. This was my next try. I know its broken but I think it gets the point across.
select *
from appointments
where staff_id = 'id'
and (to_timestamp(appointments.start_time)) > (current_date - interval concat(extract(dow from current_date), ' days'))
and (to_timestamp(appointments.start_time)) < (current_date + interval concat(7 - extract(dow from current_date), ' days'))
How would I go about building this query?
If you agree with Postgres's definition of a week, then you can do:
select a.*
from appointments a
where staff_id = 'id' and
to_timestamp(appointments.start_time) >= date_trunc('week', current_date) and
to_timestamp(appointments.start_time) < date_trunc('week', current_date) + interval '1 week';