TDengine 日期函数 DATE 用户手册

DATE

sql 复制代码
DATE(expr)

功能说明:返回输入时间表达式的日期部分。

版本:v3.3.8.0

返回结果类型:VARCHAR。

适用数据类型:表示时间戳的 BIGINT、TIMESTAMP 类型,或符合 ISO8601/RFC3339 标准的日期时间格式的 VARCHAR、NCHAR 类型。

嵌套子查询支持:适用于内层查询和外层查询。

适用于:表和超级表。

使用说明

  1. 返回格式 :返回日期的格式为 yyyy-mm-dd

  2. NULL 值处理

    • expr 为 NULL,返回 NULL。
    • expr 为 VARCHAR、NCHAR 类型但不符合 ISO8601/RFC3339 标准,返回 NULL。
  3. 精度处理

    • 输入时间表达式的精度由所查询表的精度确定。
    • 未指定表时,精度默认为毫秒。
  4. 时区处理

    • 输入与返回值的时区与客户端的系统时区一致。
    • 为避免转换时使用了非预期的时区,推荐在输入时间表达式中携带时区信息。
  5. 输入格式支持

    • BIGINT 类型:Unix 时间戳(毫秒、微秒或纳秒,取决于数据库精度)
    • TIMESTAMP 类型:直接使用时间戳列
    • VARCHAR/NCHAR 类型:符合 ISO8601/RFC3339 标准的日期时间字符串

举例

(注意:示例语句在 UTC+0800 时区执行,精度为毫秒)

sql 复制代码
-- 基础示例:从时间戳获取日期
taos> select date(946656000000);
       date(946656000000)       |
=================================
 2000-01-01                     |

-- 从日期时间字符串获取日期
taos> select date('2000-01-01 12:00:00.000');
 date('2000-01-01 12:00:00.000') |
==================================
 2000-01-01                      |

-- 从 TIMESTAMP 列获取日期
taos> select date(ts) from meters limit 3;
        date(ts)        |
=========================
 2024-01-15             |
 2024-01-15             |
 2024-01-15             |

-- NULL 值处理
taos> select date(NULL);
      date(null)        |
=========================
 NULL                   |

-- 不符合标准的字符串返回 NULL
taos> select date('invalid-date');
 date('invalid-date')   |
=========================
 NULL                   |

DATE 函数智能电表应用场景

准备工作:创建数据库、表和插入测试数据

sql 复制代码
-- 创建数据库(毫秒精度)
CREATE DATABASE IF NOT EXISTS power PRECISION 'ms';
USE power;

-- 创建智能电表超级表
CREATE STABLE IF NOT EXISTS meters (
    ts TIMESTAMP,
    current FLOAT,
    voltage INT,
    phase FLOAT
) TAGS (
    groupid INT,
    location VARCHAR(64)
);

-- 创建子表
CREATE TABLE IF NOT EXISTS d1001 USING meters TAGS (1, 'Beijing');
CREATE TABLE IF NOT EXISTS d1002 USING meters TAGS (1, 'Shanghai');
CREATE TABLE IF NOT EXISTS d1003 USING meters TAGS (2, 'Guangzhou');
CREATE TABLE IF NOT EXISTS d1004 USING meters TAGS (2, 'Shenzhen');

-- 插入测试数据(2024年1月15日全天数据)
INSERT INTO d1001 VALUES 
('2024-01-15 00:00:00', 10.2, 220, 0.95),
('2024-01-15 06:00:00', 10.5, 221, 0.96),
('2024-01-15 12:00:00', 11.2, 222, 0.97),
('2024-01-15 18:00:00', 10.8, 221, 0.96),
('2024-01-15 23:00:00', 10.1, 220, 0.95);

INSERT INTO d1001 VALUES 
('2024-01-16 00:00:00', 10.3, 220, 0.95),
('2024-01-16 12:00:00', 11.5, 223, 0.98),
('2024-01-16 23:00:00', 10.0, 219, 0.94);

INSERT INTO d1002 VALUES 
('2024-01-15 00:00:00', 9.8, 219, 0.94),
('2024-01-15 06:00:00', 10.1, 220, 0.95),
('2024-01-15 12:00:00', 10.8, 221, 0.96),
('2024-01-15 18:00:00', 10.4, 220, 0.95),
('2024-01-15 23:00:00', 9.9, 219, 0.94);

INSERT INTO d1003 VALUES 
('2024-01-15 00:00:00', 10.6, 221, 0.96),
('2024-01-15 08:00:00', 11.0, 222, 0.97),
('2024-01-15 16:00:00', 11.3, 223, 0.98),
('2024-01-15 23:00:00', 10.7, 221, 0.96);

INSERT INTO d1004 VALUES 
('2024-01-15 00:00:00', 9.5, 218, 0.93),
('2024-01-15 12:00:00', 10.2, 220, 0.95),
('2024-01-15 23:00:00', 9.8, 219, 0.94);

场景一:按日期统计电表电流和电压数据

业务需求:电力公司需要统计每个电表每天的电流、电压平均值,用于生成日报表。

sql 复制代码
-- 统计每个电表每天的电流、电压数据
SELECT 
    tbname AS meter_id,
    location,
    groupid,
    DATE(ts) AS reading_date,
    COUNT(*) AS reading_count,
    ROUND(AVG(current), 2) AS avg_current,
    ROUND(AVG(voltage), 2) AS avg_voltage,
    ROUND(AVG(phase), 3) AS avg_phase,
    MAX(current) AS peak_current,
    MAX(voltage) AS max_voltage
FROM meters
WHERE ts >= '2024-01-15 00:00:00' AND ts < '2024-01-17 00:00:00'
GROUP BY tbname, location, groupid, DATE(ts)
ORDER BY groupid, meter_id, reading_date;

预期输出示例

复制代码
 meter_id | location  | groupid | reading_date | reading_count | avg_current | avg_voltage | avg_phase | peak_current | max_voltage |
====================================================================================================================================
 d1001    | Beijing   |       1 | 2024-01-15   |             5 |       10.56 |      220.80 |     0.958 |        11.20 |         222 |
 d1001    | Beijing   |       1 | 2024-01-16   |             3 |       10.60 |      220.67 |     0.957 |        11.50 |         223 |
 d1002    | Shanghai  |       1 | 2024-01-15   |             5 |       10.20 |      219.60 |     0.948 |        10.80 |         221 |
 d1003    | Guangzhou |       2 | 2024-01-15   |             4 |       10.90 |      221.75 |     0.968 |        11.30 |         223 |
 d1004    | Shenzhen  |       2 | 2024-01-15   |             3 |        9.83 |      219.00 |     0.940 |        10.20 |         220 |

场景二:查询特定日期的电表数据

业务需求:运维人员需要快速查询某个特定日期的所有电表读数,用于故障排查或数据核对。

sql 复制代码
-- 查询 2024 年 1 月 15 日的所有电表数据
SELECT 
    tbname AS meter_id,
    location,
    groupid,
    ts,
    current,
    voltage,
    phase
FROM meters
WHERE DATE(ts) = '2024-01-15'
ORDER BY groupid, meter_id, ts;

-- 或者使用更高效的时间范围查询(推荐)
SELECT 
    tbname AS meter_id,
    location,
    groupid,
    ts,
    current,
    voltage,
    phase
FROM meters
WHERE ts >= '2024-01-15 00:00:00' AND ts < '2024-01-16 00:00:00'
ORDER BY groupid, meter_id, ts;

预期输出示例

复制代码
 meter_id | location  | groupid | ts                          | current | voltage | phase |
================================================================================================
 d1001    | Beijing   |       1 | 2024-01-15 00:00:00.000     |    10.2 |     220 |  0.95 |
 d1001    | Beijing   |       1 | 2024-01-15 06:00:00.000     |    10.5 |     221 |  0.96 |
 d1001    | Beijing   |       1 | 2024-01-15 12:00:00.000     |    11.2 |     222 |  0.97 |
 d1001    | Beijing   |       1 | 2024-01-15 18:00:00.000     |    10.8 |     221 |  0.96 |
 d1001    | Beijing   |       1 | 2024-01-15 23:00:00.000     |    10.1 |     220 |  0.95 |
 d1002    | Shanghai  |       1 | 2024-01-15 00:00:00.000     |     9.8 |     219 |  0.94 |
 ...

场景三:按日期分组统计用电情况

业务需求:管理层需要查看每天各个电表组的用电统计情况。

sql 复制代码
-- 按日期和组别统计用电情况
SELECT 
    DATE(ts) AS report_date,
    groupid,
    COUNT(tbname) AS meter_count,
    COUNT(*) AS total_readings,
    ROUND(AVG(current), 2) AS avg_current,
    ROUND(AVG(voltage), 2) AS avg_voltage,
    ROUND(AVG(phase), 3) AS avg_phase,
    MAX(current) AS peak_current,
    MIN(voltage) AS min_voltage
FROM meters
WHERE ts >= '2024-01-15 00:00:00' AND ts < '2024-01-17 00:00:00'
GROUP BY DATE(ts), groupid
ORDER BY report_date, groupid;

预期输出示例

复制代码
 report_date | groupid | meter_count | total_readings | avg_current | avg_voltage | avg_phase | peak_current | min_voltage |
================================================================================================================================
 2024-01-15  |       1 |           2 |             10 |       10.38 |      220.20 |     0.953 |        11.20 |         219 |
 2024-01-15  |       2 |           2 |              7 |       10.44 |      220.57 |     0.956 |        11.30 |         218 |
 2024-01-16  |       1 |           1 |              3 |       10.60 |      220.67 |     0.957 |        11.50 |         219 |

场景四:检测电表电压异常的日期

业务需求:质量控制团队需要检测电表数据中电压异常的记录,按日期汇总。

sql 复制代码
-- 检测电压异常的记录(电压低于 215V 或高于 225V)
SELECT 
    DATE(ts) AS abnormal_date,
    tbname AS meter_id,
    location,
    COUNT(*) AS abnormal_count,
    MIN(voltage) AS min_voltage,
    MAX(voltage) AS max_voltage,
    ROUND(AVG(voltage), 2) AS avg_voltage
FROM meters
WHERE voltage < 215 OR voltage > 225
GROUP BY DATE(ts), tbname, location
ORDER BY abnormal_date, abnormal_count DESC;

-- 按日期统计电压异常的电表数量
SELECT 
    DATE(ts) AS abnormal_date,
    COUNT(tbname) AS abnormal_meter_count,
    COUNT(*) AS abnormal_reading_count,
    ROUND(AVG(voltage), 2) AS avg_abnormal_voltage
FROM meters
WHERE voltage < 215 OR voltage > 225
GROUP BY DATE(ts)
ORDER BY abnormal_date;

场景五:电表数据按日期过滤与筛选

业务需求:数据分析师需要提取特定日期范围内的电表数据,用于趋势分析。

sql 复制代码
-- 提取最近 7 天的电表数据(假设当前日期为 2024-01-17)
SELECT 
    tbname AS meter_id,
    DATE(ts) AS reading_date,
    COUNT(*) AS daily_readings,
    ROUND(AVG(current), 2) AS avg_current,
    ROUND(AVG(voltage), 2) AS avg_voltage,
    ROUND(AVG(phase), 3) AS avg_phase
FROM meters
WHERE DATE(ts) >= '2024-01-15' AND DATE(ts) <= '2024-01-16'
GROUP BY tbname, DATE(ts)
ORDER BY meter_id, reading_date;

-- 统计工作日的电表数据(周一至周五)
SELECT 
    tbname AS meter_id,
    DATE(ts) AS reading_date,
    WEEKDAY(ts) AS weekday,
    COUNT(*) AS reading_count,
    ROUND(AVG(current), 2) AS avg_current
FROM meters
WHERE DATE(ts) >= '2024-01-15' 
  AND DATE(ts) < '2024-02-01'
  AND WEEKDAY(ts) BETWEEN 0 AND 4 
GROUP BY tbname, DATE(ts), WEEKDAY(ts)
ORDER BY meter_id, reading_date;

预期输出示例

复制代码
 meter_id | reading_date | daily_readings | avg_current | avg_voltage | avg_phase |
====================================================================================
 d1001    | 2024-01-15   |              5 |       10.56 |      220.80 |     0.958 |
 d1001    | 2024-01-16   |              3 |       10.60 |      220.67 |     0.957 |
 d1002    | 2024-01-15   |              5 |       10.20 |      219.60 |     0.948 |
 d1003    | 2024-01-15   |              4 |       10.90 |      221.75 |     0.968 |
 d1004    | 2024-01-15   |              3 |        9.83 |      219.00 |     0.940 |

场景六:跨日期的电表数据聚合分析

业务需求:管理层需要查看不同时间粒度的用电统计,包括日、周、月的对比分析。

sql 复制代码
-- 按日期统计,同时计算周、月信息
SELECT 
    DATE(ts) AS reading_date,
    WEEK(ts, 1) AS week_of_year,
    TO_CHAR(ts, 'YYYY-MM') AS year_month,
    COUNT(tbname) AS active_meters,
    COUNT(*) AS total_readings,
    ROUND(AVG(current), 2) AS avg_current,
    ROUND(AVG(voltage), 2) AS avg_voltage,
    ROUND(AVG(phase), 3) AS avg_phase
FROM meters
WHERE ts >= '2024-01-01' AND ts < '2024-04-01'
GROUP BY DATE(ts), WEEK(ts, 1), TO_CHAR(ts, 'YYYY-MM')
ORDER BY reading_date;

预期输出示例

复制代码
 reading_date | week_of_year | year_month | active_meters | total_readings | avg_current | avg_voltage | avg_phase |
======================================================================================================================
 2024-01-15   |            3 | 2024-01    |             4 |             17 |       10.40 |      220.35 |     0.954 |
 2024-01-16   |            3 | 2024-01    |             1 |              3 |       10.60 |      220.67 |     0.957 |

场景七:DATE 与其他时间函数组合使用

业务需求:综合使用多个时间函数进行复杂的时间维度分析。

sql 复制代码
-- 综合日期分析:包含日期、星期、月份等多维度信息
SELECT 
    tbname AS meter_id,
    DATE(ts) AS reading_date,
    TO_CHAR(ts, 'Day') AS day_name,
    WEEKDAY(ts) AS weekday_num,
    DAYOFWEEK(ts) AS day_of_week,
    COUNT(*) AS reading_count,
    ROUND(AVG(current), 2) AS avg_current,
    ROUND(AVG(voltage), 2) AS avg_voltage
FROM meters
WHERE ts >= '2024-01-15 00:00:00' AND ts < '2024-01-17 00:00:00'
GROUP BY tbname, DATE(ts), TO_CHAR(ts, 'Day'), WEEKDAY(ts), DAYOFWEEK(ts)
ORDER BY meter_id, reading_date;

预期输出示例

复制代码
 meter_id | reading_date | day_name  | weekday_num | day_of_week | reading_count | avg_current | avg_voltage |
=================================================================================================================
 d1001    | 2024-01-15   | Monday    |           0 |           2 |             5 |       10.56 |      220.80 |
 d1001    | 2024-01-16   | Tuesday   |           1 |           3 |             3 |       10.60 |      220.67 |
 d1002    | 2024-01-15   | Monday    |           0 |           2 |             5 |       10.20 |      219.60 |
 d1003    | 2024-01-15   | Monday    |           0 |           2 |             4 |       10.90 |      221.75 |
 d1004    | 2024-01-15   | Monday    |           0 |           2 |             3 |        9.83 |      219.00 |

场景八:基于日期的电表运行状态报表

业务需求:运营部门需要生成每日电表运行报表,包含当日运行状态汇总。

sql 复制代码
-- 生成每日电表运行状态报表
SELECT 
    DATE(ts) AS report_date,
    COUNT(tbname) AS total_meters,
    COUNT(*) AS total_readings,
    ROUND(COUNT(*) * 1.0 / COUNT( tbname), 2) AS avg_readings_per_meter,
    ROUND(AVG(current), 2) AS avg_current,
    ROUND(AVG(voltage), 2) AS avg_voltage,
    MIN(voltage) AS min_voltage,
    MAX(voltage) AS max_voltage,
    ROUND(AVG(phase), 3) AS avg_phase,
    SUM(CASE WHEN voltage < 215 OR voltage > 225 THEN 1 ELSE 0 END) AS abnormal_voltage_count,
    SUM(CASE WHEN phase < 0.9 THEN 1 ELSE 0 END) AS low_phase_count
FROM meters
WHERE ts >= '2024-01-15 00:00:00' AND ts < '2024-01-17 00:00:00'
GROUP BY DATE(ts)
ORDER BY report_date;

预期输出示例

复制代码
 report_date | total_meters | total_readings | avg_readings_per_meter | avg_current | avg_voltage | min_voltage | max_voltage | avg_phase | abnormal_voltage_count | low_phase_count |
=====================================================================================================================================================================================================
 2024-01-15  |            4 |             17 |                   4.25 |       10.40 |      220.35 |         218 |         223 |     0.954 |                      0 |               0 |
 2024-01-16  |            1 |              3 |                   3.00 |       10.60 |      220.67 |         219 |         223 |     0.957 |                      0 |               0 |

场景九:按日期分析电表功率因数

业务需求:电力质量分析团队需要按日期统计各电表的功率因数(phase)表现。

sql 复制代码
-- 按日期统计电表功率因数
SELECT 
    DATE(ts) AS analysis_date,
    tbname AS meter_id,
    location,
    COUNT(*) AS sample_count,
    ROUND(AVG(phase), 3) AS avg_phase,
    ROUND(MIN(phase), 3) AS min_phase,
    ROUND(MAX(phase), 3) AS max_phase,
    SUM(CASE WHEN phase < 0.90 THEN 1 ELSE 0 END) AS low_pf_count,
    SUM(CASE WHEN phase >= 0.95 THEN 1 ELSE 0 END) AS good_pf_count
FROM meters
WHERE ts >= '2024-01-15 00:00:00' AND ts < '2024-01-17 00:00:00'
GROUP BY DATE(ts), tbname, location
ORDER BY analysis_date, avg_phase;

预期输出示例

复制代码
 analysis_date | meter_id | location  | sample_count | avg_phase | min_phase | max_phase | low_pf_count | good_pf_count |
==============================================================================================================================
 2024-01-15    | d1004    | Shenzhen  |            3 |     0.940 |     0.930 |     0.950 |            0 |             1 |
 2024-01-15    | d1002    | Shanghai  |            5 |     0.948 |     0.940 |     0.960 |            0 |             2 |
 2024-01-15    | d1001    | Beijing   |            5 |     0.958 |     0.950 |     0.970 |            0 |             5 |
 2024-01-15    | d1003    | Guangzhou |            4 |     0.968 |     0.960 |     0.980 |            0 |             4 |
 2024-01-16    | d1001    | Beijing   |            3 |     0.957 |     0.940 |     0.980 |            0 |             2 |

DATE 函数使用最佳实践

性能优化建议

sql 复制代码
-- ✅ 推荐:直接使用时间范围过滤(可以使用索引)
SELECT * FROM meters 
WHERE ts >= '2024-01-15 00:00:00' AND ts < '2024-01-16 00:00:00';

-- ❌ 避免:使用 DATE 函数过滤(无法使用索引)
SELECT * FROM meters 
WHERE DATE(ts) = '2024-01-15';

-- ✅ 但在 GROUP BY 中使用 DATE 函数是合理的
SELECT DATE(ts), COUNT(*) FROM meters 
WHERE ts >= '2024-01-15 00:00:00' AND ts < '2024-01-16 00:00:00'
GROUP BY DATE(ts);

时区处理建议

sql 复制代码
-- ✅ 推荐:在输入字符串中明确指定时区
SELECT DATE('2024-01-15 08:00:00+08');

-- ✅ 使用 TIMEZONE() 函数确认当前时区
SELECT TIMEZONE();

与聚合函数配合使用

sql 复制代码
-- 按日期分组统计
SELECT 
    DATE(ts) AS `date`,
    COUNT(*) AS `count`,
    AVG(current) AS avg_current,
    AVG(voltage) AS avg_voltage
FROM meters
WHERE ts >= '2024-01-01'
GROUP BY DATE(ts)
ORDER BY date;

关于 TDengine

TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。

相关推荐
oMcLin3 分钟前
如何在AlmaLinux 9上优化MariaDB Galera Cluster,提升数据库集群的事务一致性与并发处理能力?
数据库·mariadb
yuankunliu3 分钟前
【redis】1、Redis的安装部署
数据库·redis·缓存
SmartRadio4 分钟前
MK8000(UWB射频芯片)与DW1000的协议适配
c语言·开发语言·stm32·单片机·嵌入式硬件·物联网·dw1000
model20055 分钟前
mariadb系统盘迁移数据盘
数据库·mariadb
项目整合库10 分钟前
Coinstore B.KU 数字金融与 RWA 主题活动圆满举行
大数据·金融
kekekka24 分钟前
2026年软文营销平台深度甄选指南:破解选择困境,聚焦长效价值
大数据·媒体
华奥系科技27 分钟前
老旧社区适老化智能改造,两个系统成社区标配项目
大数据·人工智能
码农学院30 分钟前
使用腾讯翻译文本
服务器·数据库·c#
@zulnger40 分钟前
正则表达式
数据库·正则表达式
Jackyzhe1 小时前
Flink源码阅读:Netty通信
大数据·flink