У вас может быть такой запрос:
with data as (
select 5238797 as user, TIME "08:00:00" as start_time, TIME "10:00:00" as end_time
union all
select 3919833 as user, TIME "08:00:00" as start_time, TIME "11:30:00" as end_time
union all
select 4903371 as user, TIME "09:00:00" as start_time, TIME "15:00:00" as end_time
), slots as (
SELECT
num,
time_add(time(8,0,0),INTERVAL 30*num minute ) as slot,
data.*
FROM UNNEST(GENERATE_ARRAY(0,16)) AS num
cross join data
), t as (
select slots.*, if(slot between start_time and end_time,user,null) as works from slots
), t_final as (
select slot,count(distinct works) from t
group by 1
order by 1
)
select * from t_final
, который возвращает:
+----------+-----+
| slot | cc |
+----------+-----+
| 08:00:00 | 2 |
+----------+-----+
| 08:30:00 | 2 |
+----------+-----+
| 09:00:00 | 3 |
+----------+-----+
| 09:30:00 | 3 |
+----------+-----+
| 10:00:00 | 3 |
+----------+-----+
| 10:30:00 | 2 |
+----------+-----+
| 11:00:00 | 2 |
+----------+-----+
| 11:30:00 | 2 |
+----------+-----+
| 12:00:00 | 1 |
+----------+-----+
| 12:30:00 | 1 |
+----------+-----+
| 13:00:00 | 1 |
+----------+-----+
| 13:30:00 | 1 |
+----------+-----+
| 14:00:00 | 1 |
+----------+-----+
| 14:30:00 | 1 |
+----------+-----+
| 15:00:00 | 1 |
+----------+-----+
| 15:30:00 | 0 |
+----------+-----+
| 16:00:00 | 0 |
+----------+-----+