零代码ETL实战:学生考勤画像标签系统搭建
学校考勤管理是个老大难问题——数据散落在多张表里,统计口径全靠人工拍脑袋,每学期做汇总都得半天折腾。这次我们用"数智教育"竞赛的公开数据集,拿助睿数智(Uniplore)零代码ETL平台走一遍完整流水线:把3张核心表拉通、自动打标签、按学生维度聚合,最终产出一张标准化的考勤画像标签表。。数据集包含7张业务表:教师信息()、学生信息()、考勤主表()、考勤类型码表()、成绩表()、考试类型码表()、
零代码ETL实战:学生考勤画像标签系统搭建
前言
学校考勤管理是个老大难问题——数据散落在多张表里,统计口径全靠人工拍脑袋,每学期做汇总都得半天折腾。这次我们用"数智教育"竞赛的公开数据集,拿助睿数智(Uniplore)零代码ETL平台走一遍完整流水线:把3张核心表拉通、自动打标签、按学生维度聚合,最终产出一张标准化的考勤画像标签表。
平台地址:https://lab.guilian.cn/,官网:https://www.uniplore.com/。
数据集包含7张业务表:教师信息(1_teacher.csv)、学生信息(2_student_info.csv)、考勤主表(3_kaoqin.csv)、考勤类型码表(4_kaoqintype.csv)、成绩表(5_chengji.csv)、考试类型码表(6_exam_type.csv)、消费表(7_consumption.csv)。本文只用考勤相关的前4张,核心就3张。
一、方案设计
1.1 三张核心表
考勤分析直接用星型模型,三张表各司其职:
- 考勤主表(
3_kaoqin.csv):事实表,存每天每个人的原始打卡记录。 - 考勤类型码表(
4_kaoqintype.csv):维度表,给考勤类型ID配上有意义的事件名称,标签全靠它。 - 学生信息表(
2_student_info.csv):属性表,用来补齐性别、住校状态等基础信息。
| 数据源表 | 作用 | 关键字段 |
|---|---|---|
| 考勤主表(3_kaoqin) | 存储每日考勤原始明细 | 学生ID、班级ID、学期(qj_term)、打卡时间(DataDateTime)、考勤类型ID(ControllerID)、考勤描述(controler_name) |
| 考勤类型码表(4_kaoqintype) | 标准化考勤事件名称 | 考勤类型ID(controller_id)、考勤事件名称(control_task_name) |
| 学生信息表(2_student_info) | 补充学生基础属性 | 学生ID(bf_StudentID)、班级ID(cla_id)、姓名(bf_Name)、性别(bf_sex)、出生日期(bf_BornDate)、政治面貌(bf_policy)、是否住校(bf_zhusu) |
1.2 标签体系
输出标签分三类:基础属性、衍生维度、行为统计。
基础属性标签
| 标签字段 | 数据来源 | 设计依据 |
|---|---|---|
| 学生ID | 考勤主表 / 学生信息表 | 唯一标识,关联用 |
| 学生姓名 | 考勤主表 / 学生信息表 | 方便查阅核对 |
| 班级ID | 考勤主表 / 学生信息表 | 按班级出统计 |
| 班级名称 | 考勤主表 / 学生信息表 | 用于提取年级、校区类型 |
| 性别 | 学生信息表 | 分性别做考勤分析 |
| 出生日期 | 学生信息表 | 分年龄段做分析 |
| 政治面貌 | 学生信息表 | 按政治面貌分组统计 |
衍生维度标签
| 标签字段 | 衍生逻辑 | 设计依据 |
|---|---|---|
| 年级 | 从班级名称(cla_name)提取关键词 | 按年级分层管理 |
| 是否住校 | 映射 bf_zhusu 字段(1→"是",0→"否",空值→"未知") | 住校/走读作息差异大,分群分析 |
| 校区类型 | 班级名称前缀判断("白-"或"东-"开头→新校区,其余→老校区) | 新老校区对比分析 |
行为统计标签
| 标签字段 | 设计依据 |
|---|---|
| 迟到次数 | 时间管理能力与纪律意识核心指标 |
| 早退次数 | 同上 |
| 请假次数 | 区分正常缺勤 vs 违纪,不算在迟到早退里 |
| 没穿校服次数 | 日常行为规范考核 |
1.3 统计口径
为了保证统计结果不会因为理解偏差而翻车,所有口径先定死。
基础属性处理规则
| 字段 | 处理方式 | 说明 |
|---|---|---|
| 学生ID / 学生姓名 / 班级ID / 班级名称 | 直接读 | 从考勤主表取 |
| 性别 / 出生日期 / 政治面貌 | 空值替换 | 从学生信息表取,空的填"未知" |
衍生维度处理规则
| 字段 | 处理方式 | 说明 |
|---|---|---|
| 年级 | 关键词匹配 | 班级名含"高一"→"高一",“高二"→"高二”,“高三"→"高三”,其余→"未知" |
| 是否住校 | 编码映射+空值替换 | bf_zhusu=1→"是",0→"否",空→"未知" |
| 校区类型 | 前缀判断 | 班级名以"白-“或"东-“开头→"新校区”,其他→"老校区” |
行为指标统计规则
| 指标 | 统计逻辑 | 说明 |
|---|---|---|
| 迟到次数 | COUNT(含"迟到"或"晚到"且不含"请假") | 排除请假,避免重复计 |
| 早退次数 | COUNT(含"早退"且不含"请假") | 同上 |
| 请假次数 | COUNT(含"请假") | 事假、病假全算,不跟迟到早退混淆 |
| 没穿校服次数 | COUNT(含"校服") | 考勤类型里"校服[移动考勤]"就是没穿的记录 |
三个核心原则: 请假不算迟到/早退(正常缺勤 vs 违纪要分开)、请假全覆盖(无论什么类型都算)、校服关键词出现即违规。
1.4 ETL流水线架构
整条流水线按这个顺序走:拉数据 → 关联整合 → 标签标记 → 分组聚合 → 属性补齐 → 结果入库。全流程在助睿平台的可视化拖拽界面上完成,不写一行SQL以外的代码。
| 组件 | 作用 |
|---|---|
| 表输入 | 从数据库读原始表 |
| 排序记录 | 给数据排序,给记录集连接做准备 |
| 记录集连接 | 按关联字段做多表合并 |
| 字段选择 | 只留有用字段,去冗余 |
| JavaScript脚本 | 关键词匹配,自动标记迟到/早退/请假/没校服 |
| 分组 | 按学生维度聚合,SUM出各类统计次数 |
| 替换NULL值 | 空字段统一填"未知" |
| 值映射 | 编码值(0/1)转成可读文本(否/是) |
| 表输出 | 加工完的数据写入结果表 |
二、搭建过程
2.1 准备工作:导入数据 & 建库建表
2.1.1 把CSV拉到私有文件库
先切到"文件库",右键根目录"新建目录"。





































































































































































































































































































































































7cfe3a2f81414244835b5f422b24edcb-20260521221618-noy2obt.png&pos_id=img-AKpfnMP3-1779374731588)
目录名填"数智教育数据集",确定。
去公共空间 → 数据资源。

找到 3_kaoqin.csv,点卡片右上角的"更多" → “导出”。

目标目录选刚才建的"数智教育数据集",确定。

目录下应该已经有 3_kaoqin.csv 了。

如法炮制,把 4_kaoqintype.csv 和 2_student_info.csv 也都导出到同一个目录。

2.1.2 连接数据库
进"元数据"tab,右键"关系数据库" → “新建数据源”。

弹窗里配置以下信息:
- 连接类型:MySQL
- 主机:助教给的地址(
rm-2vc3qok06bag39a5n.mysql.cn-chengdu.rds.aliyuncs.com) - 端口:3306
- 数据库名:助教给的库名
- 用户名/密码:助教给的
- 驱动:MySQL 8+
- 连接名:团队私有数据库

填完点"测试",看到"数据库连接成功"就对了。

点"添加",关系数据库下面多出一个子节点。

2.1.3 建表 + 导入原始数据
① 考勤记录表
先建个新转换流,叫"创建原始_学生考勤表",拖一个"执行SQL脚本"组件进来。

数据库连接选"团队私有数据库",填入以下SQL:
CREATE TABLE IF NOT EXISTS `raw_attendance` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`attendance_id` varchar(64) DEFAULT NULL COMMENT '考勤ID',
`learn_term` varchar(30) DEFAULT NULL COMMENT '学期',
`data_datetime` varchar(50) DEFAULT NULL COMMENT '时间和日期',
`attendance_type_id` varchar(64) DEFAULT NULL COMMENT '考勤类型ID',
`attendance_name` varchar(100) DEFAULT NULL COMMENT '考勤名称',
`attendance_task_order_id` varchar(64) DEFAULT NULL COMMENT '考勤事件ID',
`stu_id` varchar(64) DEFAULT NULL COMMENT '学生ID',
`stu_name` varchar(100) DEFAULT NULL COMMENT '学生姓名',
`cla_name` varchar(100) DEFAULT NULL COMMENT '班级名',
`cla_id` varchar(64) DEFAULT NULL COMMENT '班级ID',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '入库时间',
PRIMARY KEY (`id`),
KEY `idx_student_id` (`stu_id`),
KEY `idx_term` (`learn_term`)
) COMMENT='原始_学生考勤表';
其他参数不动,配好后长这样:

执行,画布下面能看到运行日志。

表建好了,接下来把CSV灌进去。新建转换流"导入原始考勤数据",拖一个"CSV文件输入"和"表输出"到画布。

双击CSV输入组件,名称填"考勤记录"。

点"浏览文件",选 3_kaoqin.csv,确定。

分隔符和封闭符用默认,编码选 UTF-8。

往下滑,在字段表格空白处右键"获取字段"。

获取到了就点确认。

拖"表输出"到画布上,建一条从"考勤记录"到"表输出"的连线,类型选"主输出步骤"(之后所有连线都选这个,省略不提)。

双击表输出组件,数据库连接选"团队私有数据库",目标表填 raw_attendance。

切到"数据库字段"tab,右键空白处"获取字段映射"。

把映射关系跟建表字段一一对上,确认。

执行转换流。

② 考勤类型表
操作跟上一小节一样,换张表和SQL就行。建表脚本:
CREATE TABLE IF NOT EXISTS `raw_attendance_type` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`attendance_type_id` varchar(64) NOT NULL COMMENT '考勤类型id',
`attendance_type_name` varchar(100) DEFAULT NULL COMMENT '考勤类型名称',
`attendance_task_order_id` varchar(64) DEFAULT NULL COMMENT '考勤事件id',
`attendance_task_name` varchar(100) DEFAULT NULL COMMENT '考勤事件名',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '入库时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_attendance_type_id` (`attendance_task_order_id`)
) COMMENT='原始_考勤类型表';
注意: 考勤类型CSV的分隔符不是逗号,是制表符(TAB),编码选 GB2312,别搞错了。

获取字段:

表输出配置跟前面一样,目标表换成 raw_attendance_type。


配置完执行。

③ 学生信息表
继续照搬流程,建表SQL如下:
CREATE TABLE IF NOT EXISTS `raw_student_info` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`stu_id` varchar(64) NOT NULL COMMENT '学生ID',
`stu_name` varchar(100) DEFAULT NULL COMMENT '学生姓名',
`stu_sex` varchar(10) DEFAULT NULL COMMENT '性别',
`stu_nation` varchar(50) DEFAULT NULL COMMENT '民族',
`born_date` varchar(10) DEFAULT NULL COMMENT '出生日期(年)',
`cla_name` varchar(100) DEFAULT NULL COMMENT '班级名',
`native_place` varchar(200) DEFAULT NULL COMMENT '家庭住址',
`residence_type` varchar(50) DEFAULT NULL COMMENT '家庭类型',
`policy` varchar(50) DEFAULT NULL COMMENT '政治面貌',
`cla_id` varchar(64) DEFAULT NULL COMMENT '班级ID',
`cla_term` varchar(30) DEFAULT NULL COMMENT '班级学期',
`live_on_campus` varchar(10) DEFAULT NULL COMMENT '是否住校',
`leave_school` varchar(10) DEFAULT NULL COMMENT '是否退学',
`dormitory_no` varchar(50) DEFAULT NULL COMMENT '宿舍号',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '入库时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_student_id` (`stu_id`),
KEY `idx_cla_id` (`cla_id`)
) COMMENT='原始_学生信息表';
建完表后用CSV输入组件读 2_student_info.csv:

获取字段时记得把 bf_leaveSchool 类型改成 String。

注意:
bf_zhusu和bf_qinshihao是整型,为了避免跑出小数来,中间加一个"字段选择"组件做类型固化。
拉一个"字段选择"到画布,连上CSV输入。双击进入配置,切"元数据",插入两行,把这两个字段按下面设置:


最后接表输出写入 raw_student_info:


执行就行了。
2.1.4 创建结果标签表
新建转换流"创建学生考勤主题标签表",拖"执行SQL脚本"组件,填以下建表SQL:
CREATE TABLE IF NOT EXISTS student_attendance_stats (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '自增主键',
student_id INT NOT NULL COMMENT '学生ID',
student_name VARCHAR(50) NOT NULL COMMENT '学生姓名',
class_id INT NOT NULL COMMENT '班级ID',
class_name VARCHAR(50) NOT NULL COMMENT '班级名称',
grade VARCHAR(10) NOT NULL COMMENT '年级',
gender VARCHAR(10) NOT NULL COMMENT '性别',
birth_date VARCHAR(10) NOT NULL COMMENT '出生日期',
political_status VARCHAR(20) NOT NULL COMMENT '政治面貌',
is_boarder VARCHAR(10) NOT NULL COMMENT '是否住校',
campus_type VARCHAR(10) NOT NULL COMMENT '校区类型',
late_count INT NOT NULL DEFAULT 0 COMMENT '迟到次数',
early_leave_count INT NOT NULL DEFAULT 0 COMMENT '早退次数',
leave_count INT NOT NULL DEFAULT 0 COMMENT '请假次数',
uniform_violate_count INT NOT NULL DEFAULT 0 COMMENT '没穿校服次数',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '统计入库时间',
INDEX idx_student (student_id),
INDEX idx_class (class_id),
INDEX idx_grade (grade)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学生考勤主题标签表';
配好长这样:

执行完看到成功日志即可。

2.2 核心ETL流水线:学生考勤标签构建
2.2.1 流水线总览
核心流程就六个字:读 → 合 → 标 → 算 → 补 → 存。
- 读: 从数据库拉三张原始表
- 合: 先把考勤记录和考勤类型连上(补齐事件名称),再把结果和学生信息连上(补齐属性)
- 标: JS脚本自动识别迟到、早退、请假、没校服
- 算: 按学生分组SUM
- 补: 空值替换、编码转中文、年级/校区衍生
- 存: 写进
student_attendance_stats
用到的组件已经在前面1.4列过了,下面一步步来。
2.2.2 拉取源数据
在资源库右键根目录,新建"学生考勤主题标签"转换流。

从组件库搜"表输入",拖3个到画布。

依次配置三个表输入:
- 第一个 → 名称"考勤记录",连接"团队私有数据库",选
raw_attendance表获取全部字段



- 第二个 → 名称"考勤类型",选
raw_attendance_type,同样全字段

- 第三个 → 名称"学生信息",选
raw_student_info,全字段

2.2.3 关联考勤记录 ↔ 考勤类型
考勤主表里只有考勤类型ID,没有具体的事件名(“迟到”、"早退"这些),所以要跟考勤类型码表做关联。
拖"记录集连接"组件出来,先连上"考勤记录"。连线时平台会弹"排序需要"的提示——记录集连接本质上按顺序匹配数据,如果无序可能连错。

在"考勤记录"和"记录集连接"中间加个"排序记录"组件。

双击排序记录,获取字段后只保留 attendance_type_id 和 attendance_task_order_id(这两个就是接下来连接用的键),命名为"按照考勤类型和考勤任务类型排序"。

然后把"考勤类型"表输入也连到记录集连接——考勤类型数据默认就按这两个字段升序排的,不用额外加排序组件。

双击记录集连接,配连接字段:

点"获得连接字段"后删掉多余的,两个Transform只留 attendance_type_id 和 attendance_task_order_id。
2.2.4 行为标签:JS自动标记
加"JavaScript代码"组件,接在记录集连接后面。

双击组件,名字改为"提取异常考勤记录",Script1里输入以下代码:
// 初始化变量
var isLate = 0;
var isEarly = 0;
var isLeave = 0;
var isNoUniform = 0;
// 核心判断逻辑
if(attendance_type_name != null && attendance_task_name != null){
// 迟到判断(排除请假)
if((attendance_type_name.includes("迟到") ||
attendance_type_name.includes("晚到") ||
attendance_task_name.includes("迟到") ||
attendance_task_name.includes("晚到")) &&
!attendance_task_name.includes("请假")){
isLate = 1;
}
// 早退判断(排除请假)
if((attendance_type_name.includes("早退") ||
attendance_task_name.includes("早退")) &&
!attendance_task_name.includes("请假")){
isEarly = 1;
}
// 校服违规:只要包含"校服"就标记违规
if(attendance_type_name.includes("校服") || attendance_task_name.includes("校服")){
isNoUniform = 1;
}
}
// 请假判断
if(attendance_task_name != null){
if(attendance_task_name.includes("请假")){
isLeave = 1;
}
}
配置截图:

用"获取变量"让平台自动识别脚本里定义的输出字段。

点"测试脚本",确认结果字段只有0和1,没有跑偏。

预览一目了然:

2.2.5 分组聚合
把标记好的明细数据按学生维度聚合成统计指标。拖一个"分组"组件接上JS的输出。

双击分组,分组字段设为 stu_id、stu_name、cla_id、cla_name:

聚合字段设置如下(全部用SUM):
isLate→late_count(迟到次数)isEarly→early_count(早退次数)isLeave→leave_count(请假次数)isNoUniform→no_uniform_count(没穿校服次数)

2.2.6 关联学生信息
聚合后的数据还缺性别、政治面貌、住校状态等属性,需要关联学生信息表。
先给"学生信息"那边加个排序组件。因为学号不是升序的,直接连可能出问题。连"学生信息"表输入到新的"排序记录",只保留 stu_id 字段排序,命名为"按照学生编号进行排序"。


拖第二个"记录集连接"(下面叫它"记录集连接1")到画布,连上"按照学生编号进行排序"。

考勤这边的数据也不是按学号排的,也要加排序。“分组"后面接一个"排序记录”,按 stu_id 排,命名为"考勤数据按学号排序"。


再把"考勤数据按学号排序"连到"记录集连接1"。

双击"记录集连接1":
- 第一个Transform选"考勤数据按学号排序"
- 第二个Transform选"按照学生编号进行排序"
- 连接类型:LEFT OUTER

分别点两个Transform的"获得连接字段",两边都只保留 stu_id。

2.2.7 精简字段
三张表关联完,字段多得爆炸,很多跟考勤统计没关系的列都得去掉。拖"字段选择"连到"记录集连接1"后面。

双击,名称写"移除冗余字段",切"移除"tab,右键"获取字段"。

只保留下面这些,其余全删:
stu_id(学生ID)stu_name(学生姓名)cla_id(班级ID)cla_name(班级名称)late_count(迟到次数)early_count(早退次数)leave_count(请假次数)no_uniform_count(没穿校服次数)stu_sex(性别)born_date(出生日期)policy(政治面貌)live_on_campus(是否住校)

右键组件"显示输出字段"检查一下是不是留对了。

2.2.8 NULL值处理
"替换NULL值"组件连在字段选择后面。

勾选"选择字段",在空白处右键"插入",依次把下面四个字段的空值替换为"未知":
| 字段 | 替换值 |
|---|---|
stu_sex |
未知 |
born_date |
未知 |
policy |
未知 |
live_on_campus |
未知 |


全部搞定后:
2.2.9 属性标准化
此时住校状态还是数字,而且没有年级、校区字段,需要统一处理。
① 住校状态映射
加"值映射"组件,接替换NULL值后面。

名称"住校状态映射",字段选 live_on_campus,默认值填"否"。插入两行映射:
| 源值 | 目标值 |
|---|---|
| 0 | 否 |
| 1 | 是 |



② 从班级名提取年级
拖"JavaScript代码"组件,接"住校状态映射"后面。

名称"从班级提取年级",代码:
var gra_name
if (cla_name == null){
gra_name='未知'
}else if(cla_name.includes('高一')){
gra_name='高一'
}else if (cla_name.includes('高二')){
gra_name='高二'
}else if (cla_name.includes("高三")){
gra_name='高三'
} else{
gra_name='未知'
}

在下方空白表格右键插入新行,字段名 gra_name,类型 String,替换字段名选"否"。


③ 校区类型判定
再加一个"JavaScript代码"组件,命名为"校区类型判定",代码:
var class_campus_type
if (cla_name == null){
class_campus_type='未知'
}else if(cla_name.startsWith('白-') || cla_name.startsWith('东-')){
class_campus_type='新校区'
}else if (cla_name != null && !isEmpty(cla_name)){
class_campus_type='老校区'
} else{
class_campus_type='未知'
}
字段名 class_campus_type,类型 String,替换字段名选"否"。

2.2.10 写入结果表
最后一步,拖"表输出"连在校区类型判定后面。

双击配置:
- 数据库连接:团队私有数据库
- 目标表:student_attendance_stats
- 勾选 “裁剪表”(每次先清空再写,避免重复插入)
- 勾选 “指定数据库字段”

切"数据库字段"tab,右键获取字段,逐一映射:

2.2.11 运行 & 验证
点工具栏的"执行",日志面板会实时刷新。

跑完后去"元数据"tab,右键"团队私有数据库" → “加载元数据”。

进入数据探查,展开"团队私有数据库",双击 student_attendance_stats,选"查询"tab。


看一下数据是否符合预期。

至此,一条完整的考勤画像标签ETL流水线就跑通了。从原始CSV到标准化的统计结果,全程在助睿平台上通过拖拽搞定,不需要写复杂的ETL代码。
更多推荐



所有评论(0)