# 2 實時數倉即席查詢場景的解決方法

## 2.1 函數拼接法

• 方法特點：
• 時間數據以`時間戳`形式存儲在數據庫，而非以`時間字符串`
• 查詢時實時運算時間段

• 數據量大、或併發量大時，需考慮數據庫的計算資源（CPU、內存）是否充裕
• 案例1

``````concat( toString(toHour(create_time , '{{timeZone}}')) , ':' , toString( FLOOR( toMinute(create_time , '{{timeZone}}') / 30 ) * 30 ) ) as time_period -- eg. '8:0' / '18:30'
``````

• 案例2

``````formatDateTime(
toDate(alarm_recent_time, '{{timeZone}}'),
floor(
dateDiff('minute', toDate(alarm_recent_time, '{{timeZone}}') , toDateTime(alarm_recent_time, '{{timeZone}}')) / 30 ,
0
) * 30
)
, '%H:%M'
) as timePeriod
``````

## 2.2 查詢SQL按不同情況手動分隔時間段

• 方法特點
• 時間以`時間戳`形式存儲在數據庫
• 不建議/不適用於需要分幾十上百個時段的情況（SQL會非常冗長、易錯）
• 案例

``````...

(case
when driverTime >= 0 and driverTime < 1800 then '0.0h-0.5h' -- 駕駛時長(單位：秒) := D 檔信號個數 * tsp.vehicle_status_upload_frequency(30s)
when driverTime >= 1800 and driverTime < 3600 then '0.5h-1.0h'
when driverTime >= 3600 and driverTime < 7200 then '1.0h-2.0h'
when driverTime >= 7200 and driverTime < 10800 then '2.0h-3.0h'
when driverTime >= 10800 and driverTime < 14400 then '3.0h-4.0h'
when driverTime >= 14400 and driverTime < 21600 then '4.0h-6.0h'
else '≥6.0h'
END) as drivingTimePeriod

...
UNION ALL

(
select '0.0h-0.5h' as drivingTimePeriod, 0 as vehicleCount
union all
select '0.5h-1.0h' as drivingTimePeriod, 0 as vehicleCount
union all
select '1.0h-2.0h' as drivingTimePeriod, 0 as vehicleCount
union all
select '2.0h-3.0h' as drivingTimePeriod, 0 as vehicleCount
union all
select '3.0h-4.0h' as drivingTimePeriod, 0 as vehicleCount
union all
select '4.0h-6.0h' as drivingTimePeriod, 0 as vehicleCount
union all
select '≥6.0h' as drivingTimePeriod, 0 as vehicleCount
)

...
``````

## 2.3 寫入數據庫時即存儲時段字段(timePeriod)

• 方法特點
• 不適用於分不同時區查詢/分析數據的情況

TODO