TDengine TIMETRUNCATE 函數用戶使用手冊
函數概述
TIMETRUNCATE
是 TDengine 中的一個時間處理標量函數,用于將時間戳按照指定的時間單位進行截斷操作。該函數在時間數據聚合、分組和統計分析中非常有用,特別適用于智能電表等時序數據的分析場景。
語法
TIMETRUNCATE(expr, time_unit [, use_current_timezone])
參數說明
參數 | 類型 | 必需 | 說明 |
---|---|---|---|
expr | TIMESTAMP/BIGINT/VARCHAR/NCHAR | 是 | 要截斷的時間表達式 |
time_unit | 時間單位標識符 | 是 | 時間單位,不使用引號 |
use_current_timezone | INT | 否 | 是否使用當前時區(0=UTC,1=當前時區),默認為1 |
支持的時間單位
時間單位 | 說明 | 示例 |
---|---|---|
1b | 納秒 | 截斷到納秒 |
1u | 微秒 | 截斷到微秒 |
1a | 毫秒 | 截斷到毫秒 |
1s | 秒 | 截斷到秒 |
1m | 分鐘 | 截斷到分鐘 |
1h | 小時 | 截斷到小時 |
1d | 天 | 截斷到天 |
1w | 周 | 截斷到周(從周四開始) |
返回值
- 返回類型:TIMESTAMP
- 精度:與當前數據庫設置的時間精度一致
- 特殊情況:輸入不符合時間日期格式的字符串時返回 NULL
支持的輸入類型
- TIMESTAMP 類型:標準時間戳
- BIGINT 類型:Unix 時間戳
- VARCHAR/NCHAR 類型:符合 ISO8601/RFC3339 標準的日期時間格式字符串
使用示例
基礎截斷操作
-- 使用test數據庫的智能電表數據
USE test;-- 截斷到秒(注意時間單位不使用引號)
SELECT TIMETRUNCATE('2023-10-15 14:30:25.123', 1s);
-- 結果: 2023-10-15 14:30:25.000-- 截斷到分鐘
SELECT TIMETRUNCATE('2023-10-15 14:30:25', 1m);
-- 結果: 2023-10-15 14:30:00.000-- 截斷到小時
SELECT TIMETRUNCATE('2023-10-15 14:30:25', 1h);
-- 結果: 2023-10-15 14:00:00.000-- 截斷到天
SELECT TIMETRUNCATE('2023-10-15 14:30:25', 1d);
-- 結果: 2023-10-15 00:00:00.000
智能電表數據應用示例
1. 按小時統計電表數據
-- 統計每小時的平均電流和電壓
SELECT TIMETRUNCATE(ts, 1h) as hour_time,AVG(current) as avg_current,AVG(voltage) as avg_voltage,COUNT(*) as data_count
FROM test.meters
WHERE ts >= '2023-10-01' AND ts < '2023-10-02'
GROUP BY TIMETRUNCATE(ts, 1h)
ORDER BY hour_time;
2. 按天分組分析電表讀數
-- 統計每天各個位置的電表數據
SELECT TIMETRUNCATE(ts, 1d) as day_time,location,AVG(current) as daily_avg_current,MAX(voltage) as daily_max_voltage,MIN(voltage) as daily_min_voltage
FROM test.meters
WHERE ts >= '2023-10-01'
GROUP BY TIMETRUNCATE(ts, 1d), location
ORDER BY day_time, location;
3. 特定子表的分鐘級數據統計
-- d0電表的分鐘級功率分析
SELECT TIMETRUNCATE(ts, 1m) as minute_time,AVG(current * voltage) as avg_power,MAX(phase) as max_phase
FROM test.d0
WHERE ts >= NOW() - 1d
GROUP BY TIMETRUNCATE(ts, 1m)
ORDER BY minute_time;
4. 按周統計不同組別的電表數據
-- 按周統計不同groupid的電表數據
SELECT TIMETRUNCATE(ts, 1w) as week_time,groupid,COUNT(*) as weekly_readings,AVG(current) as weekly_avg_current
FROM test.meters
WHERE ts >= '2023-09-01'
GROUP BY TIMETRUNCATE(ts, 1w), groupid
ORDER BY week_time, groupid;
時區處理示例
-- 使用 UTC 時區截斷(假設當前時區為 UTC+8)
SELECT TIMETRUNCATE(ts, 1d, 0) as utc_day,COUNT(*) as count
FROM test.meters
WHERE ts >= '2023-10-15' AND ts < '2023-10-16'
GROUP BY TIMETRUNCATE(ts, 1d, 0);-- 使用當前時區截斷
SELECT TIMETRUNCATE(ts, 1d, 1) as local_day,COUNT(*) as cnt
FROM test.meters
WHERE ts >= '2023-10-15' AND ts < '2023-10-16'
GROUP BY TIMETRUNCATE(ts, 1d, 1);
復雜業務場景應用
1. 電表異常檢測(按小時分析)
-- 檢測每小時電壓異常的電表
SELECT TIMETRUNCATE(ts, 1h) as hour_time,location,COUNT(*) as abnormal_count
FROM test.meters
WHERE voltage > 250 OR voltage < 200
GROUP BY TIMETRUNCATE(ts, 1h), location
HAVING COUNT(*) > 5
ORDER BY hour_time DESC;
2. 電表負載分析(按日統計)
-- 每日用電負載分析
SELECT TIMETRUNCATE(ts, 1d) as date,SUM(current * voltage) / 1000 as daily_power_kwh,AVG(current * voltage) as avg_power_w
FROM test.meters
WHERE location = 'Beijing.Chaoyang'
GROUP BY TIMETRUNCATE(ts, 1d)
ORDER BY date;
3. 多表對比分析
-- 對比不同電表同一小時的數據
SELECT TIMETRUNCATE(d0.ts, 1h) as hour_time,AVG(d0.current) as d0_avg_current,AVG(d1.current) as d1_avg_current,AVG(d0.voltage) as d0_avg_voltage,AVG(d1.voltage) as d1_avg_voltage
FROM test.d0, test.d1
WHERE TIMETRUNCATE(d0.ts, 1h) = TIMETRUNCATE(d1.ts, 1h)AND d0.ts >= '2023-10-15' AND d0.ts < '2023-10-16'AND d1.ts >= '2023-10-15' AND d1.ts < '2023-10-16'
GROUP BY TIMETRUNCATE(d0.ts, 1h)
ORDER BY hour_time;
注意事項和最佳實踐
1. 語法要點
- 時間單位不使用引號:
1s
、1h
、1d
等(這是關鍵區別) - 函數返回的時間戳精度與數據庫設置一致
- 輸入時間戳精度由查詢表的精度決定
2. 時區處理要點
use_current_timezone
參數僅對1d
和1w
時間單位有效- 默認使用當前時區進行截斷(
use_current_timezone=1
) - 在分析跨時區的智能電表數據時需特別注意時區設置
3. 周截斷特殊性
- 周截斷基于 Unix 時間戳計算(1970年1月1日為起點)
- Unix 時間戳起始于周四,因此所有周截斷結果都是周四
- 這與常見的周一作為一周開始的習慣不同
4. 性能優化建議
-- 在大數據量查詢中,建議在 WHERE 條件中先過濾時間范圍
SELECT TIMETRUNCATE(ts, 1h) as hour_time,AVG(current) as avg_current
FROM test.meters
WHERE ts >= '2023-10-15' AND ts < '2023-10-16' -- 先過濾時間范圍
GROUP BY TIMETRUNCATE(ts, 1h)
ORDER BY hour_time;
5. 錯誤處理
-- 無效的時間格式會返回 NULL
SELECT TIMETRUNCATE('invalid-date', 1d);
-- 結果: NULL-- 時間單位如果用引號包圍會導致語法錯誤
SELECT TIMETRUNCATE('2023-10-15', '1s');
-- 錯誤: syntax error-- 正確寫法(不使用引號)
SELECT TIMETRUNCATE('2023-10-15', 1s);
智能電表場景的實用技巧
1. 創建時間維度視圖
-- 創建按小時聚合的電表數據視圖
CREATE VIEW hourly_meter_stats AS
SELECT TIMETRUNCATE(ts, 1h) as hour,location,groupid,AVG(current) as avg_current,AVG(voltage) as avg_voltage,AVG(phase) as avg_phase,COUNT(*) as reading_count
FROM test.meters
GROUP BY TIMETRUNCATE(ts, 1h), location, groupid;
2. 定時報表查詢
-- 生成月度電表使用報告
SELECT TIMETRUNCATE(ts, 1d) as date,location,SUM(current * voltage * 24) / 1000 as estimated_daily_kwh
FROM test.meters
WHERE ts >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY TIMETRUNCATE(ts, 1d), location
ORDER BY date DESC, estimated_daily_kwh DESC;
常見問題
Q1: 為什么時間單位不需要引號?
A: 根據源碼分析,TIMETRUNCATE 函數的 time_unit 參數被定義為特殊的時間單位標識符,不是普通的字符串參數,因此不需要用引號包圍。
Q2: 如何實現按周一開始的周截斷?
A: 可以通過時間偏移來實現:
# 使用毫秒偏移(3天 = 3 * 24 * 60 * 60 * 1000 = 259200000 毫秒)
SELECT TIMETRUNCATE(ts + 259200000, 1w) - 259200000 as monday_week
FROM test.meters;
Q3: 在智能電表數據分析中,建議使用哪種時間單位?
A:
- 實時監控:使用
1m
或1s
- 趨勢分析:使用
1h
或1d
- 長期統計:使用
1d
或1w
Q4: 時間單位參數的語法規則是什么?
A: 時間單位參數必須是不帶引號的標識符,格式為數字+單位字母,如 1s
、1m
、1h
、1d
、1w
等。
相關函數
TO_TIMESTAMP()
: 字符串轉時間戳TO_ISO8601()
: 時間戳轉 ISO8601 格式字符串TIMEDIFF()
: 計算時間差NOW()
: 獲取當前時間戳