3. 关键字段解析
跨表关联的成败,往往不取决于 SQL 写得多复杂,而取决于是否真正读懂了字段。成交表与委托表看似字段名相近,语义却各有侧重:委托表记录“我想做什么”,成交表记录“实际发生了什么”。本节围绕证券代码、委托编号、成交编号、时间戳、价格、数量、买卖方向这几类关键字段,逐一说明它们的语义、格式与关联时的注意事项。
一、证券代码:关联的第一道门槛
证券代码是两表关联的基础维度,但它的格式在不同数据源中差异很大。常见形式包括纯数字(如 600519)、带市场后缀(如 600519.SH、000001.SZ)、带交易所前缀(如 SH600519),以及港股的五位代码(如 00700.HK)。如果委托表用纯数字、成交表带后缀,直接 ON a.code = b.code 会全部失配。
实操中应先做格式归一:统一补齐位数、统一大小写、剥离或补全市场标识。例如把 600519.SH 拆成代码 600519 与市场 SH 两列,再以“代码+市场”作为联合关联键,比单纯用代码更稳妥,因为不同市场可能存在相同数字代码。此外要警惕前导零丢失:000001 若被读成数值型会变成 1,务必以字符串类型读入。
二、委托编号与成交编号:主键与业务键的分工
委托编号(常称 order_id 或 entrust_no)是委托表的主键,标识一笔委托;成交编号(trade_id 或 exec_id)是成交表的主键,标识一笔成交。二者关系是“一对多”:一笔委托可能分多次成交,因此成交表中会重复出现同一个委托编号,而成交编号全局唯一。
关联时必须以委托编号为桥梁:成交表.order_id = 委托表.order_id。这里有两个易错点。其一,委托编号的唯一性范围要确认——是当日唯一、还是全历史唯一?若仅当日唯一,跨日关联必须叠加日期条件,否则会把不同交易日的同号委托错误合并。其二,成交编号不能用来关联委托表,它只用于成交表内部去重或与清算数据核对。判断关联是否合理,可先验证“成交表按委托编号分组后,每组成交数量之和是否不超过委托数量”。
三、时间戳:精度、时区与语义差异
时间戳是最容易被低估的字段。首先要区分语义:委托表的时间通常是“委托申报时间”,成交表的时间是“成交回报时间”,两者天然存在先后,不能要求相等。其次看精度:有的数据精确到秒(2024-06-03 09:30:15),有的到毫秒甚至微秒(09:30:15.123456),格式混用会导致排序和区间筛选出错。
还要确认时区与交易时段。A 股连续竞价从 09:30 开始,若数据带 UTC 时间戳,需先转换为北京时间再判断。实操建议统一转为标准时间类型,并保留原始字符串备查。时间字段在关联中主要承担两类作用:一是作为辅助校验,确认成交时间不早于委托时间;二是用于分时段统计,例如按分钟聚合委托与成交的转化率。
四、价格与数量:单位、精度与方向约定
价格字段的坑集中在单位和精度。A 股价格通常以“元”为单位、保留两位小数,但部分行情或柜台数据以“分”为单位存储整数(如 1688 表示 16.88 元),跨源关联前必须统一。数量字段则要区分“股”与“手”:委托数量可能以手(100 股)计,成交数量以股计,直接相加会差 100 倍。
买卖方向字段的取值也需对齐。常见编码有 B/S、1/2、买/卖,甚至用正负号表示。关联后应校验方向一致性:同一委托编号下,成交表的买卖方向应与委托表一致,若出现矛盾,说明数据源或关联键有问题。价格与数量还共同决定成交金额,可用 价格 × 数量 与成交金额字段交叉验证,发现单位错配。
五、字段格式对照与关联实现
把上述要点落成一张对照表,便于在写关联逻辑前逐项核对。下表为示例性约定,实际项目应以数据字典为准。
| 字段 | 所属表 | 语义 | 推荐格式 | 关联注意 |
|---|---|---|---|---|
| 证券代码 | 两表 | 标的标识 | 字符串,代码+市场 | 先归一,防前导零丢失 |
| 委托编号 | 两表 | 委托唯一标识 | 字符串 | 确认唯一范围,跨日加日期 |
| 成交编号 | 成交表 | 成交唯一标识 | 字符串 | 仅成交表内去重,不连委托表 |
| 时间戳 | 两表 | 申报 / 回报时刻 | 标准时间类型 | 统一时区与精度,不要求相等 |
| 价格 | 两表 | 委托价 / 成交价 | 元,两位小数 | 警惕“分”为单位的整数 |
| 数量 | 两表 | 委托量 / 成交量 | 股 | 手与股换算,×100 |
| 买卖方向 | 两表 | 买 / 卖 | 统一枚举 | 关联后校验方向一致 |
基于以上约定,一段典型的关联与校验 SQL 如下(示例,字段名按实际调整):
SELECT
o.order_id,
o.sec_code,
o.order_qty * 100 AS order_qty_shares, -- 手转股
SUM(t.trade_qty) AS filled_qty,
COUNT(t.trade_id) AS trade_cnt,
MIN(t.trade_time) AS first_fill_time
FROM entrust o
LEFT JOIN trade t
ON t.order_id = o.order_id
AND t.sec_code = o.sec_code
AND t.trade_date = o.trade_date -- 委托编号仅当日唯一时必须加
WHERE o.trade_date = '2024-06-03'
GROUP BY o.order_id, o.sec_code, o.order_qty
HAVING SUM(t.trade_qty) > o.order_qty * 100; -- 超量成交即异常
这段查询同时完成了关联、聚合与异常筛查:LEFT JOIN 保留未成交委托,HAVING 找出成交量超过委托量的记录。若结果为空,说明数量单位与关联键基本对齐;若大量记录超量,优先怀疑“手/股”未换算或委托编号跨日重复。