首页/新闻资讯/正文详情

PRQL 标准库 date 模块完全指南:to_text、now、trunc 与 diff 的跨数据库日期处理实践

发布时间:2026/9/24 19:22:03 来源:云帆数科 栏目:资讯中心
PRQL 标准库 date 模块完全指南:to_text、now、trunc 与 diff 的跨数据库日期处理实践
后端【免费下载链接】prqlPRQL is a modern language for transforming data — a simple, powerful, pipelined SQL replacement项目地址https://gitcode.com/gh_mirrors/pr/prql点击查看免费下载PRQLPipelined Relational Query Language是一种面向数据转换的现代语言其标准库中的date模块为日期与时间处理提供了to_text、now、trunc、diff四个核心函数。本指南以官方文档 web/book/src/reference/stdlib/date.md 为骨架结合仓库源码与集成测试系统讲解每个函数的用法、各数据库方言的 SQL 编译差异、完整格式说明符对照以及跨方言移植时必须注意的兼容性边界。读完本文你将能够在 BigQuery、Clickhouse、DuckDB、MySQL、MSSQL、Postgres、SQLite、Snowflake 等目标数据库上正确使用 PRQL 的日期函数并理解它们编译为 SQL 的底层机制。date 模块概览标准库中的四个日期函数date模块定义在标准库源码 prqlc/prqlc/src/semantic/std.prql 中共包含四个函数module date { # Returns the current date and time as a timestamp. let now - timestamp internal std.date.now let to_text formattext column - text internal std.date.to_text let diff noresolve.unit start end - int internal std.date.diff let trunc unittext column - internal std.date.trunc }从签名可以读出三个关键设计now是无参数函数返回timestamp类型to_text的第一个参数formattext是字符串字面量格式模板第二个参数是要格式化的列diff的单位参数unit被声明为noresolve.unit即以裸关键字形式传入如day这与trunc将单位写成字符串字面量如day形成鲜明对比trunc的单位是unittext必须为字符串字面量。这些函数的主体在std.prql中只是标记为internal std.date.*的内部占位真正实现位于 SQL 方言标准库 prqlc/prqlc/src/sql/std.sql.prql 中。由于不同 RDBMS 的日期函数差异巨大PRQL 采用通用实现 各方言覆盖的策略通用模块提供 ANSI 兼容的默认实现各数据库方言再在module date中覆盖对应函数。to_text把日期转换为文本to_text将一个日期或时间戳转换为文本。由于日期的表示形式多种多样它需要一个format参数来描述日期/时间戳的结构格式使用 日期与时间格式说明符 一节中的说明符。[!NOTE] 由于所有 RDBMS 格式化日期和时间的方式各不相同PRQL要求显式指定目标方言dialect才能编译to_text。目前受支持的数据库包括BigQuery、Clickhouse、DuckDB、MySQL、MSSQL 和 Postgres。以下是官方文档给出的三种方言示例prql target:sql.duckdb from invoices select (invoice_date | date.to_text %d/%m/%Y)prql target:sql.postgres from invoices select (invoice_date | date.to_text %d/%m/%Y)prql target:sql.mysql from invoices select (invoice_date | date.to_text %d/%m/%Y)相同的 PRQL 表达式在不同方言下会编译为各自的原生格式化函数这可以从 prqlc/prqlc/src/sql/std.sql.prql 中各方言module date的实现看出方言编译后的 SQL 函数源码位置BigQueryFORMAT_TIMESTAMP({format}, CAST({column} AS TIMESTAMP))std.sql.prql#L238-L244ClickhouseformatDateTimeInJodaSyntax({column}, {format})std.sql.prql#L258-L265DuckDBstrftime({column}, {format})std.sql.prql#L288-L293MSSQLFORMAT({column}, {format})std.sql.prql#L321-L324MySQLDATE_FORMAT({column}, {format})std.sql.prql#L340-L349PostgresTO_CHAR({column}, {format})std.sql.prql#L387-L392格式字符串的编译机制to_text的关键实现位于 prqlc/prqlc/src/sql/gen_expr.rs 的process_date_to_text函数中。该函数只接受字符串字面量作为格式参数——如果格式是列引用或任意表达式编译期会直接报错std.date.to_text only supports a string literal as format其处理流程是从参数中提取字符串字面量format调用ctx.dialect.translate_prql_date_format(format)把 PRQLchrono 风格格式转换为目标方言的格式语法生成方言对应的格式化函数调用并继续走常规的运算符翻译。格式转换的底层实现在 prqlc/prqlc/src/sql/dialect.rstranslate_prql_date_format使用 Rustchrono库的StrftimeItems逐项解析 PRQL 格式串再调用各方言的translate_chrono_item做逐项映射。由此可以推断to_text的格式语言本质上是chronostrftime 格式的一个子集。真实运行结果验证仓库集成测试 prqlc/prqlc/tests/integration/queries/date_to_text.prql 在 MSSQL 上运行了 12 种格式组合其快照 prqlc/prqlc/tests/integration/snapshots/integration__queries__results__date_to_text.snap 展示了真实输出from invoices take 20 select { d1 (invoice_date | date.to_text %Y/%m/%d), d2 (invoice_date | date.to_text %F), d3 (invoice_date | date.to_text %D), d4 (invoice_date | date.to_text %H:%M:%S.%f), d5 (invoice_date | date.to_text %r), d6 (invoice_date | date.to_text %A %B %-d %Y), d7 (invoice_date | date.to_text %a, %-d %b %Y at %I:%M:%S %p), d8 (invoice_date | date.to_text %), d9 (invoice_date | date.to_text %-d/%-m/%y), d10 (invoice_date | date.to_text %-Hh %Mmin), d11 (invoice_date | date.to_text %M%S\), d12 (invoice_date | date.to_text 100%% in %d days), }对应的部分输出以invoice_date 2009/01/01为例2009/01/01 | 2009-01-01 | 01/01/09 | 00:00:00.000000 | 12:00:00 AM Thursday January 1 2009 | Thu, 1 Jan 2009 at 12:00:00 AM 2009-01-01T00:00:00.000000Z | 1/1/09 | 0h 00min | 0000 | 100% in 01 days注意两点该测试文件头部带有# generic:skip和# sqlite:skip标记说明to_text不支持通用generic方言和 SQLite 方言——这与必须显式指定支持的方言的约束一致d11中单引号、双引号与%S、%M混合使用是合法的说明格式串可以自由混入字面量字符d12演示了转义%%输出一个字面百分号。now获取当前日期时间now返回当前日期和时间类型为时间戳timestamp。它在语义上等价于各数据库的当前时间函数常用作过滤条件例如from test_tables filter test_time date.now由于没有显式指定prql target:这段查询会按通用generic方言编译。now在不同方言下的 SQL 输出并不相同官方文档给出了对照表方言SQL 输出GenericCURRENT_TIMESTAMPMySQLNOW()BigQueryCURRENT_TIMESTAMP()Clickhousenow()其他方言CURRENT_TIMESTAMP对照 prqlc/prqlc/src/sql/std.sql.prql 源码可以看到差异的成因通用模块中let now - sCURRENT_TIMESTAMP并注释说明CURRENT_TIMESTAMP 是 ANSI SQL 标准方言可以覆盖std.sql.prql#L143-L144BigQuery 覆盖为CURRENT_TIMESTAMP()注释明确指出BigQuery 要求CURRENT_TIMESTAMP带括号std.sql.prql#L242-L243Clickhouse 覆盖为now()std.sql.prql#L264MySQL 覆盖为NOW()std.sql.prql#L345-L346。trunc按单位截断日期trunc将日期或时间戳截断到指定单位。与date.diff不同trunc的单位必须写成字符串字面量如day同时单位必须在编译期已知因此把列或任意表达式放在单位位置会直接报错。可接受的单位集合取决于目标数据库。prql target:sql.postgres from events select (event_time | date.trunc day)大多数方言把单位作为带引号的第一个参数但 MSSQL 和 BigQuery 各自采用自己的形式。官方文档给出的对照表方言SQL 输出GenericDATE_TRUNC(day, event_time)DuckDBDATE_TRUNC(day, event_time)PostgresDATE_TRUNC(day, event_time)MySQLDATE_TRUNC(day, event_time)ClickhouseDATE_TRUNC(day, event_time)SnowflakeDATE_TRUNC(day, event_time)MSSQLDATETRUNC(day, event_time)BigQueryDATE_TRUNC(event_time, DAY)通用实现位于 std.sql.prql#L154let trunc unit column - sDATE_TRUNC({unit:0}, {column:0})。MySQL 在 std.sql.prql#L348 同样实现了DATE_TRUNC其注释链接到 MySQL 8.4 的 date-trunc 文档而 MSSQL、BigQuery、Snowflake 的特殊形态目前由编译器的方言能力处理。[!NOTE] SQLite 没有任何日期截断函数因此针对 SQLite 方言编译date.trunc时会直接报错。这在 std.sql.prql#L447 中体现为let trunc unit column - null返回空实现。diff计算两个日期的时间差diff返回end减去start的结果单位为unit——即date.diff unit start end在end晚于start时取正值。与trunc相反diff的单位必须写成裸关键字如day可接受单位同样取决于目标数据库。from events derive { days_open (date.diff day start_date end_date) }date.diff编译为目标数据库自己的日期差函数因此精确的舍入行为——部分单位是否计数——遵循目标数据库的规则而不是由 PRQL 统一归一化。各方言的 SQL 输出对照方言SQL 输出GenericDATEDIFF(day, start_date, end_date)DuckDBdatediff(day, start_date, end_date)MSSQLDATEDIFF(day, start_date, end_date)MySQLTIMESTAMPDIFF(day, start_date, end_date)ClickhousedateDiff(day, start_date, end_date)BigQueryDATE_DIFF(end_date, start_date, day)SnowflakeDATEDIFF(day, start_date, end_date)源码层面的证据通用实现let diff unit start end - sDATEDIFF({unit:0}, {start:0}, {end:0})std.sql.prql#L142其上方注释罗列了 ClickHouse、DuckDB、MariaDB、MySQL、MSSQL、Snowflake、Redshift 的参考文档链接DuckDB 覆盖为datediff({unit:0}, {start:0}, {end:0})std.sql.prql#L292Clickhouse 覆盖为dateDiff({unit:0}, {start:0}, {end:0})std.sql.prql#L262MySQL 覆盖为TIMESTAMPDIFF({unit:0}, {start:0}, {end:0})std.sql.prql#L344BigQuery 覆盖为DATE_DIFF({end:0}, {start:0}, {unit:0})std.sql.prql#L241注意其参数顺序为(end, start, unit)与其他方言不同。[!NOTE] Postgres 和 SQLite 没有内置的DATEDIFF等价函数因此针对这两个方言编译date.diff会报错。在 std.sql.prql#L391 与 std.sql.prql#L446 中分别体现为let diff unit start end - nullPostgres和let diff unit start end - nullSQLite。diff 与 trunc 的参数风格差异速查函数单位写法单位必须编译期已知不支持的方言date.trunc unit column字符串字面量如day是否则报错SQLitedate.diff unit start end裸关键字如day—关键字天然固定Postgres、SQLite日期与时间格式说明符完整对照表PRQL 的日期时间格式说明符是chronostrftime 说明符的一个子集。以下是当前受支持的全部说明符说明符示例描述日期说明符DATE SPECIFIERS%Y2001年份数字零填充到 4 位%y01年份数字零填充到 2 位%m07月份数字01–12零填充到 2 位%-m7月份数字1-12不填充%bJul缩写月份名固定 3 个字母%BJuly完整月份名%d08日数字01-31零填充到 2 位%-d8日数字1-31不填充%aSun缩写星期名固定 3 个字母%ASunday完整星期名%D07/08/01月-日-年格式等价于%m/%d/%y%x07/08/01语言环境的日期表示%F2001-07-08年-月-日格式ISO 8601等价于%Y-%m-%d时间说明符TIME SPECIFIERS%H00小时数字00-23零填充到 2 位%-H0小时数字0-23不填充%I1212 小时制小时数字01--12零填充到 2 位%pAM12 小时制中的AM或PM%M34分钟数字00-59零填充到 2 位%S60秒数字00-60零填充到 2 位%f264900距上一个整秒以来的微秒数¹%R00:34时-分格式等价于%H:%M%T00:34:60时-分-秒格式等价于%H:%M:%S%X00:34:60语言环境的时间表示如 23:13:48%r12:34:60 AM语言环境的 12 小时制时间如 11:11:04 PM日期与时间说明符DATE TIME SPECIFIERS%2001-07-08T00:34:60.026490ZISO 8601 / RFC 3339 日期时间格式特殊说明符SPECIAL SPECIFIERS%t字面制表符\t%n字面换行符\n%%字面百分号空格填充说明符不受支持chrono 的%_前缀形式空格填充以及%k/%l别名在任何方言中都不受支持。¹%f与 chrono 的差异在 PRQL 中%f表示微秒microseconds这与 chrono 中%f表示纳秒nanoseconds不同。这一点在上表脚注中明确标注是迁移 chrono 格式串到 PRQL 时最容易踩的坑之一。兼容性边界与限制汇总综合官方文档与源码date模块的方言支持矩阵如下函数BigQueryClickhouseDuckDBMySQLMSSQLPostgresSQLiteSnowflaketo_text✅✅✅✅✅✅❌❌默认now✅✅✅继承通用✅✅继承通用✅继承通用✅继承通用✅继承通用trunc✅特殊语法✅✅✅✅DATETRUNC✅❌✅引号列名diff✅参数序不同✅✅✅✅❌❌✅引号列名使用时的关键注意事项to_text必须显式声明方言且只支持 BigQuery、Clickhouse、DuckDB、MySQL、MSSQL、Postgres 六个目标格式参数只能是字符串字面量见 gen_expr.rs 的编译期校验。date.trunc不适用于 SQLitedate.diff不适用于 Postgres 和 SQLite否则编译报错。diff的舍入语义不归一化——部分单位如 1.5 天是否计为 2 天完全取决于目标数据库的DATEDIFF/TIMESTAMPDIFF/dateDiff/DATE_DIFF实现PRQL 不做跨库统一。diff与trunc的单位写法不同前者用裸关键字date.diff day ...后者用字符串date.trunc day混用会编译失败。trunc的单位必须编译期已知单位位置放列名或表达式属于错误用法。%f表示微秒而非纳秒且空格填充%_、%k、%l不被任何方言支持。以上约束均有仓库源码佐证读者可通过 prqlc/prqlc/src/semantic/std.prql、prqlc/prqlc/src/sql/std.sql.prql、prqlc/prqlc/src/sql/gen_expr.rs 及集成测试 prqlc/prqlc/tests/integration/queries/date_to_text.prql 进一步深入验证。当需要实现标准库未覆盖的日期逻辑时PRQL 的 s-string 仍然是最后的逃生通道见 标准库文档。赞分享后端【免费下载链接】prqlPRQL is a modern language for transforming data — a simple, powerful, pipelined SQL replacement项目地址https://gitcode.com/gh_mirrors/pr/prql点击查看免费下载相关推荐PRQL 标准库stdlib完全指南内置函数、模块划分与跨数据库方言实现PRQL 标准库stdlib完全指南内置函数、模块划分与跨数据库方言实现 PRQL 标准库Standard Library是 PRQL 语言内置函数与后端PRQL 标准库 text 模块字符串处理函数的完整指南与 SQL 编译原理PRQL 标准库 text 模块字符串处理函数的完整指南与 SQL 编译原理 本指南聚焦 PRQL 标准库中的 text 模块系统讲解 lower 、 up后端internationalized/date 完全指南国际化日历、日期与时间处理库的 API 详解internationalized/date 完全指南国际化日历、日期与时间处理库的 API 详解 internationalized/date 是 re前端UI组件设计系统国际化状态管理上一篇TheAlgorithms/Python 维护脚本实战用 gh CLI 批量清理 Hacktoberfest 高峰期的 Pull Request下一篇Meteor 用户与账户系统完全指南密码登录、无密码登录、2FA 与 OAuth 集成实战创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

基于SSH的校园导航系统实战:从Spring整合到Dijkstra部署
基于SSH的校园导航系统实战:从Spring整合到Dijkstra部署

简介:面向高校毕业设计场景的校园导航系统完整工程包,基于SSH框架(StrutsSpringHibernate)与JSP技术构建,后端采用MySQL存储,适配JDK 1.8及Eclipse、MyEclipse、STS、IDEA等主流IDE。系统同时具备管理员、校… · 2026/9/24 19:22:03

小红书视频无水印保存全攻略:手机电脑通用抓取思路
小红书视频无水印保存全攻略:手机电脑通用抓取思路

小红书上的视频内容越来越丰富,从穿搭教程、美食探店到旅行vlog、手工diy,很多朋友看到喜欢的视频第一反应就是保存下来,方便自己反复观看或者做笔记参考。但实际操作过的都知道,直接点保存,视频左下角和右下角会带上平… · 2026/9/24 19:22:03

pandas数据处理全指南:从入门到实战
pandas数据处理全指南:从入门到实战

1. 写在前面:为什么你一定要学pandas如果你刚接触Python,或者已经写了几天代码准备往数据分析方向走,那pandas一定是绕不开的那个库。我可以直接告诉你一个判断标准:在Python的数据处理生态里,pandas就是那个“事实标准… · 2026/9/24 19:21:50

2026等保测评全攻略:新规动向、整改实操与策略选择
2026等保测评全攻略:新规动向、整改实操与策略选择

我第一次独自扛等保测评的时候,对着测评机构发来的资料清单犯了两天愁。那时候以为等保就是把防火墙、日志审计、堡垒机买齐再填一堆表格,结果真正开始整改才发现,最花时间的不是买设备,而是搞清楚每个检查项背后的意图。到2026年… · 2026/9/24 19:54:49

国产GitLab选型指南:Gitee、极狐GitLab与自建方案对比
国产GitLab选型指南:Gitee、极狐GitLab与自建方案对比

这些年问我“有没有国产 GitLab”的人越来越多了,而且问法五花八门:有人是被网络卡到崩溃,有人是被版本和合规逼的,还有人是纯粹想搞清楚 Gitee 和极狐 GitLab 这俩到底有什么区别。说实话,这个问题放在两年前还没有标… · 2026/9/24 19:54:49

前端开发者必补的后端与部署Skill:选型逻辑与实操避坑指南
前端开发者必补的后端与部署Skill:选型逻辑与实操避坑指南

前端开发者写页面写到一定阶段,几乎都会撞上同一堵墙:接口联调时后端说“字段没问题”,部署上线时运维说“环境不对”,本地跑得好好的项目一上服务器就白屏。这时候你会发现,光会写组件和调样式已经不够用了&#xff0… · 2026/9/24 19:54:49

Hadoop与PySpark对比实战:从架构原理到选型落地
Hadoop与PySpark对比实战:从架构原理到选型落地

做大数据这行,绕不开的坎就是选框架。我刚入行那会儿,被“Hadoop VS PySpark”这个问题纠结了很久,网上资料各说各话,看得人头晕。后来自己把两者都真正用了一遍,从课程设计到生产环境都踩过坑,才慢慢理清楚… · 2026/9/24 19:54:49

多数据库结构分析工具开发实战:解析MySQL、PostgreSQL与SQLite元数据
多数据库结构分析工具开发实战:解析MySQL、PostgreSQL与SQLite元数据

上个月帮朋友迁移一个老项目,需要同时核对MySQL和PostgreSQL两套库的表结构。那体验就像一个人同时用两套方言的字典查单词:MySQL里翻information_schema还算顺手,换到PostgreSQL就得去pg_catalog里对着pg_attribute、pg_class拼查询&#xf… · 2026/9/24 19:54:49

Windows HID设备枚举实战:从SetupAPI到HID Class API完整解析
Windows HID设备枚举实战:从SetupAPI到HID Class API完整解析

简介:本资源是一个基于Visual C开发的USB HID设备检测工具项目,面向Windows平台C开发者及嵌入式/驱动方向学习者,解决HID类外设(如键盘、鼠标、游戏手柄等)在PC端的自动识别与信息获取问题。项目完整封装了SetupAPI枚举… · 2026/9/24 19:54:41

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码