
DATE
sql
DATE(expr)
功能说明:返回输入时间表达式的日期部分。
版本:v3.3.8.0
返回结果类型:VARCHAR。
适用数据类型:表示时间戳的 BIGINT、TIMESTAMP 类型,或符合 ISO8601/RFC3339 标准的日期时间格式的 VARCHAR、NCHAR 类型。
嵌套子查询支持:适用于内层查询和外层查询。
适用于:表和超级表。
使用说明:
-
返回格式 :返回日期的格式为
yyyy-mm-dd。 -
NULL 值处理:
- 若
expr为 NULL,返回 NULL。 - 若
expr为 VARCHAR、NCHAR 类型但不符合 ISO8601/RFC3339 标准,返回 NULL。
- 若
-
精度处理:
- 输入时间表达式的精度由所查询表的精度确定。
- 未指定表时,精度默认为毫秒。
-
时区处理:
- 输入与返回值的时区与客户端的系统时区一致。
- 为避免转换时使用了非预期的时区,推荐在输入时间表达式中携带时区信息。
-
输入格式支持:
- 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 提供实时分析、可视化、事件管理与报警等功能。