I have a table as below in bigquery called statusChanged :
id timestamp status prev-enter-time
5d 2020-12-19 01:36 Enter 2020-12-19 00:00
5d 2020-12-19 01:40 Exit 2020-12-19 01:36
8d 2020-12-19 01:37 Enter 2020-12-19 00:00
8d 2020-12-19 01:45 Exit 2020-12-19 01:37
9m 2020-12-19 01:48 Exit 2020-12-19 00:00
So there is a specific area on the map and the table above shows the entrance and exit time of cars into that area from 2 days ago. Many cars entered 3 or more days ago and are still in so we listed prev-enter-time as beginning of 2 days ago (2020-12-19 00:00). So last row shows car 9m which exit the area at 2020-12-19 01:48 has entered the area at 2020-12-19 00:00 or before that.
I am going to calculate max and minimum number of cars in that area per hour for example if I can create this table from the above table:
car entered exited
A. 8:01 8:40
B. 8:01 8:15
C. 8:05 8:10
C. 8:16 9:30
D. 00:00 11:00
means max number of cars between 8-9 am is 4 and min number of cars is 1 because:
8:00 D ->min
8:01 A,B,D
8.05 A,B,C,D ->max
8.10 A,B,D
8.15 A,D
8.16 A,C,D
8.40 C,D
9.00 C,D
So it looks very complicated to me as we need something like histogram to moves slowly and add or remove cars entering and exiting. Timestamp has second and milliseconds which I did not show here. My solution is from the first table which is available in bigquery, create the second table which has three columns: carId, entered and exited time.Then divid each hour into second or milliseconds and calculate the number of cars in the area per second and find min an max for each hour which looks very complicated to me. Please let me know if you know how to do it.
If I understand correctly, you can unpivot the data and then use some window functions and aggregation to calculate what you want:
with ee as (
select timestamp, 1 as inc
from t
where status = 'enter'
union all
select timestamp, -1 as inc
from t
where status = 'exit'
),
ins as (
select timestamp,
sum(sum(inc)) over (order by timestamp) as num_ins
from ee
)
select timestamp_trunc(timestamp, hour) as hh,
max(num_ins) as max_ins,
min(num_ins) as min_ins
from ins
group by hh
order by hh;
I worked on it and I can create min and max per hour (I did that for 8-9 am and I have to do it for 24 hours): but this results are based on the second table which I have to create from statusChanged table:
WITH
TABLE AS (
SELECT
'A' AS car,
Timestamp '2020-12-19 8:01:00' AS entered,
Timestamp '2020-12-19 8:40:00' AS exited
UNION ALL
SELECT
'B',
Timestamp '2020-12-19 8:01:00',
Timestamp '2020-12-19 8:15:00'
UNION ALL
SELECT
'C',
Timestamp '2020-12-19 8:05:00',
Timestamp '2020-12-19 8:10:00'
UNION ALL
SELECT
'C',
Timestamp '2020-12-19 8:16:00',
Timestamp '2020-12-19 9:30:00'
UNION ALL
SELECT
'D',
Timestamp '2020-12-19 00:00:00',
Timestamp '2020-12-19 11:00:00' ),
execution_day AS (
SELECT
TIMESTAMP_ADD(TIMESTAMP_SUB(TIMESTAMP(CURRENT_DATE()), INTERVAL 2 day),INTERVAL 8 hour) executionDay,
),
zeroto59 AS (
SELECT
*
FROM
UNNEST(GENERATE_ARRAY(0, 59)) value),
minutes AS (
SELECT
TIMESTAMP_ADD(executionDay, INTERVAL value minute) minuteStart,
TIMESTAMP_ADD(executionDay, INTERVAL value + 1 minute) minuteEnd
FROM
zeroto59,
execution_day),
temp AS (
SELECT
*,
TIMESTAMP_TRUNC(entered, minute) AS minutesStart,
TIMESTAMP_TRUNC(exited, minute) AS minutesEnd
FROM
TABLE ),
temp2 AS (
SELECT
minuteStart,
COUNT(car) AS car_count
FROM
minutes,
temp
WHERE
minutesStart<=minuteStart
AND minutesEnd>= minuteEnd
GROUP BY
minuteStart)
SELECT
TIMESTAMP_TRUNC(minuteStart, hour) AS hr,
MIN(car_count) AS min,
MAX(car_count) AS max
FROM
temp2
GROUP BY
hr
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.