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 提供实时分析、可视化、事件管理与报警等功能。

相关推荐
q***65691 小时前
PostgreSQL 中进行数据导入和导出
大数据·数据库·postgresql
一 乐2 小时前
助农平台|基于SprinBoot+vue的助农服务系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·ecmascript·springboot
NineData2 小时前
保姆级!Oracle→达梦零停机迁移攻略,5 步操作,业务零影响!
数据库·程序员
q***31833 小时前
MySQL---存储过程详解
数据库·mysql
E***U9453 小时前
C在物联网中的.NET Core
物联网·.netcore
q***42823 小时前
MySQL数据库误删恢复_mysql 数据 误删
数据库·mysql·adb
2***s6723 小时前
给SQL server数据库表字段添加注释SQL,附修改、删除注释SQL及演示
数据库·sql·oracle
龙言龙论3 小时前
身份证信息批量处理系统:从入门到实战(附exe工具+核心源码)
数据库·python