month_day 如何准确处理会员生日查询?数据库存有完整出生日期,但生日营销只关心每年循环的月和日。亿问 Data Agent 将"忽略年份、只比较月日"定义为 month_day 语义类型,通过确定的规则将业务问法稳定转换为可执行的查询条件。本文从一条具体语义规则切入,展示语义层如何把项目级 SQL 提炼为系统级公共能力。
"五月份过生日的会员有哪些?"在会员运营中,这是一个基础且高频的目标人群筛选问题。
数据库存有完整出生日期,查询结果仍可能偏离业务口径。完整日期记录具体年份,生日营销关心每年循环的月和日。年份一旦进入条件,SQL 可以正常执行,查询却可能发生错选或漏选。
亿问 Data Agent 将"忽略年份、只比较月日"定义为 month_day 语义类型,统一处理月份、自然季度、单日和跨年区间。这项能力最早源自亿问服务一家中国 500 强服饰零售企业时遇到的真实会员运营需求,并持续用于该客户的日常运营。
本文聚焦语义层中一条具体的时间规则。更完整的语义建模框架可参见《语义层不能只剩指标和维度:Data Agent 时代,企业到底该建什么?》。
生日营销首先要筛出活动期内过生日的会员。在这个任务中,系统只比较出生日期中的月和日,用来判断会员是否落在活动时间范围内。
计算年龄时,同一个字段需要保留完整的年、月、日。业务任务发生变化,日期参与计算的部分也会变化。系统如果没有区分这两种含义,就可能把年份错误地带入生日筛选条件。
最初,这类需求可以在项目的数据模型(Schema)中编写转换规则,例如使用 ClickHouse 的 formatDateTime 函数提取月和日。对于单个项目,这种处理很直接。
随着同类需求进入更多项目,日期函数、格式和边界处理也需要反复配置。规则分散后,每次调整都要逐项检查,同一个业务问题很难长期保持统一口径。当"只看月日"需要被多个项目和团队反复使用时,它就有必要成为一条由系统统一定义的公共规则。
month_day 如何定义"只看月日"?month_day 表示每年循环的公历月日,不保留年份。它的物理类型为字符串,统一规范为可比较的 MM-DD 格式。
在 Schema 中,字段可以通过以下方式完成语义标记:
{
"name": "生日",
"type": "month_day"
}完成字段准备和映射后,系统便会按照月日语义处理这个字段。月份、自然季度、单日和跨年区间,也会进入同一套日期规则。
语义标记只定义字段含义,物理数据仍需单独映射。存量数据库通常需要映射已有月日列、视图列或预先生成的字段;类型声明本身不会自动派生新的物理列。
month_day 如何执行?亿问 Data Agent 会把业务人员的问题逐步转换为可执行的数据库条件:
自然语言问题 → 自研的 NL2LF2SQL 引擎(Alisa)识别业务字段和时间表达 → 生成 Logicform(逻辑形式),固定查询对象与条件 → 将月份或季度转换为日期范围 → month_day 去掉年份和时间,统一为 MM-DD → 将跨年范围拆成两个区间 → 生成 SQL 并交给数据库执行
例如,"五月份过生日"会转换为 05-01 至 05-31。查询"12 月 28 日到 1 月 3 日过生日的人"时,系统会把条件拆成 12-28 至 12-31 和 01-01 至 01-03 两个区间。
完成字段准备、映射和语义标记后,日期转换、范围拆分和查询生成都由确定规则执行。从业务问法到数据模型,再到数据库条件,这条链路把业务语言和数据处理接在一起,为生日营销提供准确、完整的目标名单。
周期日期查询通常有三种处理路线。选择取决于查询频率、应用范围和口径维护要求。
| 处理方式 | 合适场景 | 长期使用需要关注的问题 |
|---|---|---|
| 项目级 SQL 或计算字段 | 一次性分析、单个项目 | 规则复制后容易分散,数据库函数需要分别适配 |
| 提示词或动态 SQL | 快速验证新的问法 | 日期规则在查询时生成,一致性更依赖模型输出 |
| 独立语义类型 | 长期、反复使用的业务查询 | 前期需要完成字段映射,后续规则可以集中测试和修改 |
一次性分析或单个项目可以优先使用 SQL 或计算字段。同一业务口径需要长期使用,并将在多个项目或团队之间复用时,独立语义类型更便于集中测试、修改和检查。
month_day 如何在企业内保持统一口径?month_day 的首要价值,是让相同的业务口径始终按照确定规则执行。在源数据、字段映射和意图识别正确,并且问题属于已支持范围的前提下,同一种 Logicform 会进入同一套月日规则,结果会准确对应既定业务口径。
规则集中后,查询过程也更容易检查。数据团队可以确认字段使用了什么语义类型、日期范围如何转换、最终生成了什么查询条件,出现问题时更容易定位。
企业内部的职责也会更清楚:业务团队确认"月日"代表什么,数据团队完成字段映射和数据检查,系统按照统一规则执行查询。每个新的业务模型仍需完成字段标记、物理映射和数据质量检查;完成后,语义定义、日期归一化和查询重写规则可以继续沿用。
month_day?会员运营中,生日之外,入会周年和首购周年也会用到同一种时间规则。企业记录了入会日期或首次购买日期后,运营团队要找出即将到周年的会员,查询时同样只需比较月和日。
服饰零售是这套能力已经实际验证的场景。对于酒店、文旅等同样重视会员长期经营的行业,如果运营动作需要按公历月日筛选周年客群,也可以沿用这一建模思路。
行业和运营动作各有差异,系统需要理解每家企业自己的时间口径,并将其稳定转化为准确、可执行的查询规则。这些场景的共性,是每年到了某个月和某一天,都要找出符合企业业务口径的人。把这层共性写进 month_day,一个具体需求就可以沉淀为更多同类场景能够沿用的系统规则。
month_day 的准确性依赖哪些条件?month_day 将"忽略年份、只比较月日"变成确定规则。查询结果准确对应既定业务口径,还需要同时满足以下条件:
month_day。month_day 可以处理公历自然月份、自然季度、单日和跨年区间。农历生日、财务季度和时区换日具有各自的业务口径,需要单独定义。
这套规则降低了业务逻辑对某一种数据库日期函数的依赖。底层数据库发生变化时,仍需确认字段映射、条件编码和生成的 SQL 能够在新环境中正确执行。
month_day 到企业世界语义month_day 是亿问用于语义建模的一种基础类型。进入具体企业后,它需要对应真实的业务字段、运营规则和数据模型,才能成为这家企业世界语义的一部分。
每家企业的经营对象、业务流程和管理口径都不同。亿问会根据客户的实际经营情况,梳理业务对象、属性、关系和规则,在此基础上进行语义建模。
"月日"提供了一个很小的切口:从真实业务中识别具体含义,再把这层含义写进系统,让系统按照企业自己的规则理解问题、执行查询。
回到开头的问题,系统能否准确找出五月过生日的会员,取决于它是否理解"只看月日"这层业务含义。一次生日客群筛选,连接着业务理解、语义建模、工程执行和实际运营。随着更多业务规则进入语义层,企业数据分析也会逐步建立在统一、可检查的口径之上。
单个项目中完全可以,而且很直接。问题是当同类需求出现在多个项目、多个团队时,各自的日期函数、格式和边界处理容易分散。规则复制后,每次调整都要逐项检查,同一个业务问题很难长期保持统一口径。month_day 把这条规则从项目级 SQL 提升为系统级语义类型,让它在多个项目间集中测试、修改和复用。
month_day 能处理跨年查询吗?能。"12 月 28 日到 1 月 3 日过生日的人"这种跨年区间,系统会自动拆成 12-28 至 12-31 和 01-01 至 01-03 两个区间,无需人工拆分。
数据库字段类型(DATE、DATETIME、VARCHAR)描述的是数据如何存储。语义类型(month_day、datetime、year)描述的是业务含义——这个日期在业务中代表什么、应该怎么参与计算。同一个 DATE 字段,可以用作出生日期计算年龄,也可以用作 month_day 筛选生日。语义标记让系统区分这两种用途。
month_day 当前处理的是公历月日。农历生日、财务季度和时区换日具有各自的业务口径,需要单独定义语义类型和转换规则。语义层的设计让每种口径都可以独立建模,不会互相干扰。
★ 为亿问自有技术术语。词条详见「亿问技术词典」栏目。