简体   繁体   中英

Calculate max and min number of ids per hour

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM