This question already has answers here:
Postgresql SQL GROUP BY time interval with arbitrary accuracy (down to milli seconds)
(10 answers)
Closed 1 year ago.
I was wondering if you can help me write a query that should just SELECT count(*) but only include data from last 3 hours and group it by 5 minutes.
So I have a table that has a createdts so I have the date there. I just want to see how many entries I have in the last 3 hours, but group COUNT(*) per 5 minutes.
SELECT COUNT(*)
FROM mytable
WHERE createdts >= now()::date - interval '3 hour'
GROUP BY 'every 5 minutes'
Also, what's really important is that the Count(*)'s that are null, get defaulted to 0. I have many windows of time where the data will be null, and having it default to 0 saves a lot of headache later
Use generate_series():
SELECT gs.t, COUNT(t.createdts)
FROM GENERATE_SERIES(now()::date - interval '3 hour', now()::date, interval '5 minute') gs(t)
mytable t
ON t.createdts >= gs.t AND
t.createdts < gs.t + interval '5 minute'
GROUP BY gs.t;
Related
My database table looks like this:
CREATE TABLE record
(
id INT,
status INT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
And I want to create a generic query to get count of record created after 3 hours of interval in last day
For example, I want to know in last 1 day after 3 hours how many records are created.
What I have so far: with a little help from stackoverflow I am able to create a query to calculate the count for a single full day.
SELECT
DATE(created_at) AS day, COUNT(1)
FROM
record
WHERE
created_at >= current_date - 1
GROUP BY
DATE(created_at)
This is telling me in full day like 24 records are created but I want to get how many are made in interval of 3 hours
If you want the count for the last three hours of data:
select count(*)
from record
where created_at >= now() - interval '3 hour';
If you want the last day minus 3 hours, that would be 21 hours:
select count(*)
from record
where created_at >= now() - interval '21 hour';
EDIT:
You want intervals of 3 hours for the last 24 hours. The simplest method is probably generate_series():
select gs.ts, count(r.created_at)
from generate_series(now() - interval '24 hour', now() - interval '3 hour', interval '3 hour') gs(ts) left join
record r
on r.created_at >= gs.ts and
r.created_at < gs.ts + interval '3 hour'
group by gs.ts
order by gs.ts;
I need to get only entries that are 10 days + old in BigQuery, I went to other questions and google doc (which is confuse as hell) but could not find a the result I expected.
My query:
SELECT Id
FROM myTable
WHERE eventTS > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 10 DAY)
The this query is returning values that are not 10 days + old.
when I add -10 DAY doesn't return nothing.
Any help is MUCH welcome!
Thanks in advance.
Try following Bigquery functions SELECT CURRENT_TIMESTAMP() as Curr_Ts, TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 10 DAY) as Sub_Ts , TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL -10 DAY) as Add_Ts It will Add & Substract 10 days from CURRENT_TIMESTAMP(). Output will be as :-
Your Query will get modified as :-
SELECT Id
FROM myTable
WHERE eventTS < TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 10 DAY)
Or
SELECT Id
FROM myTable
WHERE eventTS < TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL -10 DAY)
Try replacing > with <:
SELECT Id
FROM myTable
WHERE eventTS < TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 10 DAY)
I want to pull orders that have been placed in between (last 5 mins - last 10 mins). For that I am running a query:
$query="SELECT * FROM orders where `orderStatus`='PARTIAL' and `timeCreated` >= date_sub(now(),interval 10 minute)";
However, this query is picking data from between (last 0 mins - last 10 mins).
Can you please help what should I try?
Just add another filtering condition:
SELECT *
FROM orders
WHERE
orderStatus = 'PARTIAL'
AND timeCreated >= date_sub(now(), interval 10 minute)
AND timeCreated < date_sub(now(), interval 5 minute);
Assuming that you are using MySQL (the syntax of your existing query suggests it), you can also phrase the query using the following date arithmetics, which I find more straight-forward:
SELECT *
FROM orders
WHERE
orderStatus = 'PARTIAL'
AND timeCreated >= now() - interval 10 minute
AND timeCreated < now() - interval 5 minute
I am writing a query that counts trips which exceed 20 minutes but is only in the years 2015, 2016, 2017. The code works fine, showing the years and number of trips per year, but the results show all years and not just these three. The issue is that the column start_time is a timestamp. I can do timestamp_add and then between (as shown below, disregard the number of days as they are just placeholders) but it just seems sloppy
I can do timestamp_add and then between (as shown below, disregard the number of days as they are just placeholders) but it just seems sloppy.
SELECT extract(year from start_time), count(*)
FROM `datapb.shopping.trips`
where duration_minutes > 20 and
start_time between timestamp_add(current_timestamp(), interval -1000 DAY) AND timestamp_add(current_timestamp(), interval -350 DAY)
group by EXTRACT(YEAR from start_time)
Any suggestions would be fantastic, thanks!
Why not just use timestamp constants?
select extract(year from start_time) as yyyy, count(*)
from `datapb.shopping.trips`
where duration_minutes > 20 and
start_time >= timestamp('2015-01-01') and
start_time < timestamp('2018-01-01')
group by yyyy
order by yyyy;
I have a scenario where there are cases and multiple calls are made to customers against those cases. All these call logs are in a table which has following columns -
id primary key int
case_id int
call_made_at timestamp
I have to find number of new calls(1st call made for any case) made in last 7 days and number of old calls (any call which is not 1st call for any case) in last 7 days.
I can use row_number() with partition over case_id. But lifetime of case id is not much. So doing a partition on the entire table seems bad. Also table will soon become huge.
Any suggestions?
I see this as aggregation, not window functions:
select sum(case when min_cma >= current_date - interval '7 day' then 1 else 0 end) as last_7_days,
sum(case when max_cma >= current_date - interval '7 day' and
min_cms < current_date - interval '7 day'
then 1 else 0 end) as
from (select cl.case_id,
min(call_made_at) as min_cma,
max(call_made_at) as max_cma
from call_logs cl
group by cl.case_id
) cl;
You can add something like where max_cma >= current_date - interval '7 day' to the outer query. It will probably improve performance.