ActionTran:数量对齐 + 规则必兑现 + Java/Groovy 同构
修订自
2026-07-20-action-tran-count-align-extract-design.md。补强:detect 命中的可自动改写规则必须真正改写;Java 与平台 Groovy 行为一致;以真实 meta / 样例做逐条校验。
| 项 | 路径 |
|---|---|
| 权威实现 | 20260719/gr/src/main/java/com/qvsu/actiontran/ActionTranRunApi.java |
| 规则目录 | 20260719/gr/src/main/resources/rules/auto-rules.json(与 pgjr.md Action SQL 子集) |
| 平台脚本 | 20260719/gr/examples/ActionTranRun.groovy(必须与 Java 同逻辑) |
| 手册 | 20260719/pgjr.md |
1. 成功标准
- 数量:
meta(COC, DB+CUS, s_is_del=1)=scanned=upserted(空 body / 抽不出 SQL 仍 upsert,need_update=0)。 - 改写兑现:对「可自动改写」规则,若
from/unit命中detect,则to必须完成对应转换(不得仅进match_rule而正文不变)。 - 同构:同一输入下,Java
applyRules/extractSql与 Groovy 对应方法结果一致(单测 + 共享样例)。
2. GROUP_CONCAT 根因(已核实)
| 现象 | 原因 |
|---|---|
match_rule 有 GROUP_CONCAT,to 仍含 GROUP_CONCAT |
detect=GROUP_CONCAT\s*( 易命中;rewrite.pattern 要求 SEPARATOR '…' 且 ([^)]+?) |
| 嵌套函数 | GROUP_CONCAT(IFNULL(a,''), …) 在第一个 ) 处截断,整段不匹配 |
| 手册形态 | GROUP_CONCAT(x ORDER BY y SEPARATOR ',') → STRING_AGG(x, ',' ORDER BY y);现替换会把 ORDER BY 留在错误位置 |
| 无 SEPARATOR | MySQL 默认逗号;当前正则直接不改 |
修复:内置 rewriteGroupConcat(平衡括号解析,对齐 pgjr.md 规则 21),规则 21 的 JSON rewrite 改为 annotate(目录仍可 detect;真改写走结晶方法,与 FOUND_ROWS/LIKE 同类)。
覆盖:
GROUP_CONCAT(expr SEPARATOR 's')→STRING_AGG(expr, 's')GROUP_CONCAT(DISTINCT expr SEPARATOR 's')→STRING_AGG(DISTINCT expr, 's')(DISTINCT 保留在第一参侧按 PG 习惯:STRING_AGG(DISTINCT expr, 's'))GROUP_CONCAT(expr ORDER BY … SEPARATOR 's')→STRING_AGG(expr, 's' ORDER BY …)GROUP_CONCAT(expr)/GROUP_CONCAT(expr ORDER BY …)→ 分隔符默认','
3. 其它行为(沿用上版)
- 空 units → 仍 upsert(策略 A)。
- CUS
extractSql:线性全脚本扫描(fence / 三引号 / 引号字面量),禁止宽正则、禁止整段 CUS 当 SQL。 detect仍可只扫 probe(8k)列match_rule;结晶改写必须对全文out扫描(GROUP_CONCAT 等不得因 8k 截断漏改)。JSON regex 改写:对out做rewrite.find(失败吞掉),不以 probe 作为唯一门闩。
4. Java ↔ Groovy 同构
| 能力 | Java | Groovy |
|---|---|---|
| extractSql 线性扫描 | ✓ | 必须同算法 |
| applyRules + 结晶(GROUP_CONCAT/FOUND_ROWS/LIKE/…) | ✓ | 必须同调用顺序 |
| 空 units upsert | ✓ | ✓ |
| 规则 JSON | classpath auto-rules.json |
内嵌 EMBEDDED_RULES_JSON 与 json 同内容(改规则时两端一起改) |
权威源:Java。改完后 diff 关键路径 / 用同一组 fixture 断言两侧输出一致(Groovy 侧以脚本自检或文档化手工对照清单;工程内以 Java 单测锁行为,Groovy 同步粘贴)。
5. 校验(业务准确性)
- 单测:
pgjr.md规则 21 样例 + 嵌套 IFNULL + 无 SEPARATOR + DISTINCT。 - 脚本
scripts/validate_rule_rewrites.py(MySQL 可用时):扫qvsu_meta_action,对每条 body 调用与 Java 同构的检查逻辑,或跑完/run后查qvsu_action_tran:
from含GROUP_CONCAT(且非纯注释 →to不得再含未改写的GROUP_CONCAT((允许注释残留则先剥注释再判)。 - 数量:
compare_meta_tran.py→match: YES。
6. 改动文件
ActionTranRunApi.java—rewriteGroupConcat+ applyRules 调用;regex 门闩改为对全文auto-rules.json— 规则 21 → annotateActionTranRunApiTest.java— GROUP_CONCAT 用例ActionTranRun.groovy— 同步结晶与规则嵌入scripts/validate_rule_rewrites.py— meta/tran 逐条硬规则校验RuleExamplesDocTest.java— 生成本文 §7 对照表(mvn -Dtest=RuleExamplesDocTest test→target/rule-examples-section.md)- 本文档 + plan 更新
不做:改 apply 回写;扩到 DDL 规则。
7. 规则改写对照(COC 实库 2410 条)
在线页:https://public.joysky.cloud/721-action-tran-rules/
唯一 key:
{app_name_en}|{plugin_type}|{action_name_en},对应表qvsu_action_tran唯一约束uk_app_plugin_action。关联验证示例:
sql SELECT * FROM qvsu_action_tran WHERE app_name_en='COC' AND plugin_type='DB' AND action_name_en='Mysql7';生成:
python scripts/extract_real_rule_examples.py --out …
7.1 规则 ↔ 实库脚本唯一 key 总表
unique_key =
{app_name_en}|{plugin_type}|{action_name_en}(=uk_app_plugin_action)
| 规则ID | 类别 | 标题 | rewrite | unique_key | need_update |
|---|---|---|---|---|---|
| 1 | 标识符与字面量 | 标识符引用 | regex | COC|CUS|Groovy54 |
1 |
| 2 | 标识符与字面量 | 字符串引号 | regex | COC|CUS|Groovy61 |
1 |
| 3 | 标识符与字面量 | 大小写比较 | annotate | COC|DB|Mysql1228Copy3Copy1Copy1Copy1 |
1 |
| 4 | 标识符与字面量 | LIKE / ILIKE | crystallize+regex | COC|DB|Mysql1228Copy3Copy1Copy1Copy1 |
1 |
| 5 | 标识符与字面量 | 注释 | regex | COC|DB|MysqlPlus41 |
1 |
| 6 | 标识符与字面量 | 布尔比较 | annotate | COC|DB|Mysql888_20687 |
1 |
| 7 | 标识符与字面量 | 空串与 NULL | regex | COC|CUS|Groovy61 |
1 |
| 8 | 标识符与字面量 | 库名.表名 | regex | (本批未命中) |
|
| 9 | 标识符与字面量 | 零日期 | regex | COC|DB|Mysql893_5b7fa |
1 |
| 10 | 分页与排序 | LIMIT offset,count | regex | COC|DB|Mysql555 |
0 |
| 11 | 分页与排序 | FETCH FIRST | annotate | (本批未命中) |
|
| 12 | 分页与排序 | 随机排序 | regex | (本批未命中) |
|
| 13 | 分页与排序 | FORCE INDEX | remove | (本批未命中) |
|
| 14 | 条件与逻辑函数 | IFNULL | regex | COC|CUS|Groovy61 |
1 |
| 15 | 条件与逻辑函数 | IF() | template | COC|DB|Mysql1290 |
1 |
| 16 | 条件与逻辑函数 | CASE | annotate | COC|DB|Mysql1290 |
1 |
| 17 | 条件与逻辑函数 | 空安全等于 | regex | (本批未命中) |
|
| 18 | 条件与逻辑函数 | XOR | regex | (本批未命中) |
|
| 19 | 条件与逻辑函数 | 布尔转 0/1 | annotate | COC|DB|Mysql1223Copy2Copy1Copy1Copy1Copy1 |
1 |
| 20 | 字符串函数 | CONCAT / | 与 NULL | annotate | |
| 21 | 字符串函数 | GROUP_CONCAT | crystallize+annotate | COC|DB|Mysql1378Copy1Copy1 |
1 |
| 22 | 字符串函数 | FIND_IN_SET | regex | (本批未命中) |
|
| 23 | 字符串函数 | SUBSTRING_INDEX | regex | (本批未命中) |
|
| 24 | 字符串函数 | LOCATE | regex | (本批未命中) |
|
| 25 | 字符串函数 | LENGTH / CHAR_LENGTH | annotate | COC|DB|Mysql1179 |
0 |
| 26 | 字符串函数 | 正则 | regex | (本批未命中) |
|
| 27 | 字符串函数 | CAST UNSIGNED | regex | (本批未命中) |
|
| 28 | 字符串函数 | CONVERT → CAST | regex | (本批未命中) |
|
| 29 | 字符串函数 | UUID | regex | (本批未命中) |
|
| 30 | 日期时间函数 | NOW | regex | (本批未命中) |
|
| 31 | 日期时间函数 | DATE_FORMAT | regex | COC|DB|Mysql1223Copy2Copy1Copy1Copy1 |
1 |
| 32 | 日期时间函数 | STR_TO_DATE | regex | COC|DB|Mysql220Copy1Copy1 |
0 |
| 33 | 日期时间函数 | UNIX_TIMESTAMP | regex | (本批未命中) |
|
| 34 | 日期时间函数 | FROM_UNIXTIME | regex | (本批未命中) |
|
| 35 | 日期时间函数 | DATE_ADD | regex | COC|DB|Mysql1290 |
1 |
| 36 | 日期时间函数 | DATEDIFF | regex | (本批未命中) |
|
| 37 | 日期时间函数 | DATE() | regex | COC|DB|Mysql95_bc2ecCopy1Copy1Copy1Copy1Copy1Copy1 |
0 |
| 38 | 日期时间函数 | YEAR/MONTH | regex | COC|DB|Mysql1290Copy1Copy1Copy1Copy1Copy1Copy1 |
1 |
| 39 | 日期时间函数 | CURDATE | regex | (本批未命中) |
|
| 40 | JSON | JSON path | annotate | COC|DB|Mysql1101 |
1 |
| 41 | DML | ON DUPLICATE KEY | annotate | COC|DB|MysqlPlus41 |
1 |
| 42 | DML | new_row 别名 | regex | (本批未命中) |
|
| 43 | DML | INSERT IGNORE | annotate | COC|DB|Mysql1114 |
0 |
| 44 | DML | REPLACE INTO | annotate | (本批未命中) |
|
| 45 | DML | UPDATE JOIN | annotate | COC|DB|receptionMedicalDiseaseEntryU |
0 |
| 46 | DML | DELETE JOIN | annotate | (本批未命中) |
|
| 47 | DML | 多表 DELETE | annotate | (本批未命中) |
|
| 48 | DML | 取自增 ID | annotate | (本批未命中) |
|
| 49 | 查询语义与事务 | 松散 GROUP BY | annotate | COC|DB|Mysql1290Copy1Copy1Copy1Copy1 |
1 |
| 50 | 查询语义与事务 | 隐式类型转换 | regex | (本批未命中) |
|
| 51 | 查询语义与事务 | 除法 | annotate | COC|DB|Mysql1371 |
1 |
| 52 | 查询语义与事务 | ROUND 需 numeric | regex | COC|DB|Mysql1007 |
1 |
| 53 | 查询语义与事务 | 事务中止 25P02 | annotate | (本批未命中) |
|
| 54 | 查询语义与事务 | smallint = boolean | annotate | COC|DB|Mysql1056 |
0 |
| C1 | 结晶 | SQL_CALC_FOUND_ROWS / FOUND_ROWS | crystallize | (本批未命中) |
|
| C2 | 结晶 | JSON_OBJECTAGG | crystallize | (本批未命中) |
有样例 29 / 未命中 27(COC 2410 条覆盖)。
7.2 按规则的改前 / 改后截取
规则 1 · 标识符引用(regex)
- unique_key:
COC|CUS|Groovy54 - plugin_type / action_name_en:
CUS/Groovy54 - need_update:
1(选取=match_rule)
改前(截取)
…re.toolkit.StringUtils.sqlArgsFill("INSERT INTO `mn_daily_order` " +
"(`order_id`, `client_id`,`account_id`, `treatment_type`, `order_all_money`, `order_actual_money`, `order_collection_money`, " +
"`order_time`, `status`, `salesman`, `optometrist`, `make_single`, `order_remark`, `tracking_number`, " +
"`col…
改后(截取)
…re.toolkit.StringUtils.sqlArgsFill("INSERT INTO mn_daily_order " +
"(`order_id`, `client_id`,`account_id`, `treatment_type`, `order_all_money`, `order_actual_money`, `order_collection_money`, " +
"`order_time`, `status`, `salesman`, `optometrist`, `make_single`, `order_remark`, `…
规则 2 · 字符串引号(regex)
- unique_key:
COC|CUS|Groovy61 - plugin_type / action_name_en:
CUS/Groovy61 - need_update:
1(选取=match_rule)
改前(截取)
…static final String UPLOAD_INIT_DATA_JSON_URL = "/qvsu/files/json/initData/";
private FileServerInfo fileServerInfo = SpringUtils.getBean(FileServerInfo.class);
// private FileServerService fileServerService = SpringUtils.getBean(FileServerService.class);
// private AmazonS3 amazonS3 = SpringUtils.getBean(AmazonS3.class)
Object groovy(HashMap<String, Object> actionMap, HashMap<St…
改后(截取)
…appVersion ,pro,file_visit_url as fileVisitUrl,COALESCE(use_file_visit,'0') as useFileVisit from qvsu_run_app " +
"where s_is_del=1 and app_name_en ={0} order by appVersion+0 DESC limit 1", appNameEn);
if (map == null || map.size() == 0) {
return Collections.EMPTY_MAP
}…
规则 3 · 大小写比较(annotate)
- unique_key:
COC|DB|Mysql1228Copy3Copy1Copy1Copy1 - plugin_type / action_name_en:
DB/Mysql1228Copy3Copy1Copy1Copy1 - need_update:
1(选取=match_rule)
改前(截取)
…ime = '2026-03-31 23:59:59'
AND t.task_name ILIKE '%二档%'
AND t.executive_arm IN ({{deptD.text}}) ;
改后(截取)
…ue AS 完成值,
CONCAT(ROUND(CAST(CAST(CAST(CAST(CAST(t.progress AS numeric AS numeric AS numeric AS numeric AS numeric))))), 2), '%') AS 完成率
FROM mn_task t
LEFT JOIN opt_dept d
ON t.executive_arm = d.dept_id
AND d.s_is_del = 1
WHERE
t.s_is_del = 1
AND t.execution_start_time = '2026-01-01 00:00:00'…
规则 4 · LIKE / ILIKE(crystallize+regex)
本批未命中,无 unique_key。
规则 5 · 注释(regex)
- unique_key:
COC|DB|MysqlPlus41 - plugin_type / action_name_en:
DB/MysqlPlus41 - need_update:
1(选取=match_rule)
改前(截取)
…--{item.commodity_name},--{item.suppliers_name},#{item.suppliers_commodity_name},#{item.suppliers_commodity_id})
</foreach>
ON DUPLICATE KEY UPDATE
s_is_del=1
改后(截取)
…--{item.commodity_name},--{item.suppliers_name},--{item.suppliers_commodity_name},#{item.suppliers_commodity_id})
</foreach>
ON DUPLICATE KEY UPDATE
s_is_del=1
规则 6 · 布尔比较(annotate)
- unique_key:
COC|DB|Mysql888_20687 - plugin_type / action_name_en:
DB/Mysql888_20687 - need_update:
1(选取=match_rule)
改前(截取)
…mdr1.dept_id = od1.dept_id
WHERE mue1.is_old_user = 1
AND mdr1.state IN (2, 4)
AND (od1.dept_id = ANY(string_to_array('{{deptD.text}}', ','))) ),
0
) AS old_customer_reservation_count,
-- 老客户挂号人数
COALESCE(
(SELECT COUNT(mdr2.user_id)
FROM mn_daily_registered mdr2
JOIN mn_user_extend mue2 ON mdr2.user_id…
改后(截取)
…ELSE CONCAT(ROUND(CAST(CAST(CAST(CAST(CAST((
SELECT COUNT(mue5.user_id AS numeric AS numeric AS numeric AS numeric AS numeric))))))
FROM mn_user_extend mue5
JOIN mn_daily_order mdo5 ON mue5.user_id = mdo5.client_id
JOIN opt_dept od5 ON mdo5.outp…
规则 7 · 空串与 NULL(regex)
- unique_key:
COC|CUS|Groovy61 - plugin_type / action_name_en:
CUS/Groovy61 - need_update:
1(选取=match_rule)
改前(截取)
…appVersion ,pro,file_visit_url as fileVisitUrl,IFNULL (use_file_visit,'0') as useFileVisit from qvsu_run_app " +
"where s_is_del=1 and app_name_en ={0} order by appVersion+0 DESC limit 1", appNameEn);
if (map == null || map.size() == 0) {
return Collections.EMPTY_MAP
}
String resSql = com.baomidou.mybatisplus.core.to…
改后(截取)
…appVersion ,pro,file_visit_url as fileVisitUrl,COALESCE(use_file_visit,'0') as useFileVisit from qvsu_run_app " +
"where s_is_del=1 and app_name_en ={0} order by appVersion+0 DESC limit 1", appNameEn);
if (map == null || map.size() == 0) {
return Collections.EMPTY_MAP
}…
规则 8 · 库名.表名(regex)
本批未命中,无 unique_key。
规则 9 · 零日期(regex)
- unique_key:
COC|DB|Mysql893_5b7fa - plugin_type / action_name_en:
DB/Mysql893_5b7fa - need_update:
1(选取=body-scan)
改前(截取)
…AND (mue.first_cc_time > '{{time.value[0]||'0000-00-00'}}' - INTERVAL 30 DAY OR mue.first_cc_time IS NULL)
AND (
(DATE(mdo.order_time) between COALESCE( '{{time.value[0]||'0000-00-00'}}', '0000-00-00') and COALESCE( '{{time.value[1]||'9999-12-31'}}', '9999-12-31'))
OR
(DATE(mdo.order_time) between COALESCE( '{{time.value[0]||'0000-00-00'}}', '0000-00-…
改后(截取)
…'
ELSE CONCAT(ROUND(CAST(CAST(CAST(CAST(CAST(SUM(CASE WHEN EXTRACT(YEAR FROM mdo.order_time AS numeric AS numeric AS numeric AS numeric AS numeric)))))) = EXTRACT(YEAR FROM CURRENT_DATE) THEN mdo.order_actual_money ELSE 0 END) /
(SELECT SUM(order_actual_money) FROM mn_daily_order WHERE status = '3'…
规则 10 · LIMIT offset,count(regex)
本批未命中,无 unique_key。
规则 11 · FETCH FIRST(annotate)
本批未命中,无 unique_key。
规则 12 · 随机排序(regex)
本批未命中,无 unique_key。
规则 13 · FORCE INDEX(remove)
本批未命中,无 unique_key。
规则 14 · IFNULL(regex)
- unique_key:
COC|CUS|Groovy61 - plugin_type / action_name_en:
CUS/Groovy61 - need_update:
1(选取=match_rule)
改前(截取)
…appVersion ,pro,file_visit_url as fileVisitUrl,IFNULL (use_file_visit,'0') as useFileVisit from qvsu_run_app " +
"where s_is_del=1 and app_name_en ={0} order by appVersion+0 DESC limit 1", appNameEn);
if (map == null || map.size() == 0) {
return Collections.EMPTY_MAP
}
String resSql = com.baomidou.mybatisplus.core.to…
改后(截取)
…appVersion ,pro,file_visit_url as fileVisitUrl,COALESCE(use_file_visit,'0') as useFileVisit from qvsu_run_app " +
"where s_is_del=1 and app_name_en ={0} order by appVersion+0 DESC limit 1", appNameEn);
if (map == null || map.size() == 0) {
return Collections.EMPTY_MAP
}…
规则 15 · IF()(template)
本批未命中,无 unique_key。
规则 16 · CASE(annotate)
- unique_key:
COC|DB|Mysql1290 - plugin_type / action_name_en:
DB/Mysql1290 - need_update:
1(选取=match_rule)
改前(截取)
…S 本周开始时间,
MAX(dr.end_time) AS 本周结束时间,
COUNT(CASE WHEN status = '1' THEN follow_id END) AS 已完成随访数,
COUNT(CASE WHEN status IN ('0','1','3') THEN follow_id END) AS 应回访总数,
CONCAT(ROUND(CAST(CAST(CAST(CAST(COUNT(CASE WHEN status = '1' THEN follow_id END AS numeric AS numeric AS numeric AS numeric)))))
/
NULLIF(COUNT(CASE WHEN status IN ('0','1','3') THEN foll…
改后(截取)
…) AS 应回访总数,
CONCAT(ROUND(CAST(CAST(CAST(CAST(CAST(COUNT(CASE WHEN status = '1' THEN follow_id END AS numeric AS numeric AS numeric AS numeric AS numeric))))))
/
NULLIF(COUNT(CASE WHEN status IN ('0','1','3') THEN follow_id END), 0)
* 100, 2), '') AS 随访完成率
FROM mn_member_follow_tickets
CROSS JOIN date_ranges…
规则 17 · 空安全等于(regex)
本批未命中,无 unique_key。
规则 18 · XOR(regex)
本批未命中,无 unique_key。
规则 19 · 布尔转 0/1(annotate)
- unique_key:
COC|DB|Mysql1223Copy2Copy1Copy1Copy1Copy1 - plugin_type / action_name_en:
DB/Mysql1223Copy2Copy1Copy1Copy1Copy1 - need_update:
1(选取=match_rule)
改前(截取)
…meric AS numeric AS numeric AS numeric))))) = 1 THEN 1 END), 0), 0) AS 一月,
ROUND(CAST(CAST(CAST(CAST(COALESCE(SUM(CASE WHEN MONTH(u.filing_time AS numeric AS numeric AS numeric AS numeric))))) = 2 THEN 1 END), 0), 0) AS 二月,
ROUND(CAST(CAST(CAST(CAST(COALESCE(SUM(CASE WHEN MONTH(u.filing_time AS numeric AS numeric AS numeric AS numeric))))) = 3 THEN 1 END), 0), 0) AS 三…
改后(截取)
SELECT
ROUND(CAST(CAST(CAST(CAST(CAST(COALESCE(SUM(CASE WHEN MONTH(u.filing_time AS numeric AS numeric AS numeric AS numeric AS numeric)))))) = 1 THEN 1 END), 0), 0) AS 一月,
ROUND(CAST(CAST(CAST(CAST(CAST(COALESCE(SUM(CASE WHEN MONTH(u.filing_time AS numeric AS numeric AS numeric AS numeric AS numeric)))))) = 2 THEN…
规则 20 · CONCAT / || 与 NULL(annotate)
- unique_key:
COC|DB|Mysql1007 - plugin_type / action_name_en:
DB/Mysql1007 - need_update:
1(选取=match_rule)
改前(截取)
…TE mn_project_management
SET project_progress = CONCAT(
ROUND(CAST(CAST(CAST(CAST((project_endSteps / progress_total AS numeric AS numeric AS numeric AS numeric))))) * 100,
2
),
'%'
)
WHERE s_is_del = '1'
AND mn_project_management.project_no = {{Table2.triggeredRow.project_no}}
改后(截取)
…rogress = CONCAT(
ROUND(CAST(CAST(CAST(CAST(CAST((project_endSteps / progress_total AS numeric AS numeric AS numeric AS numeric AS numeric)))))) * 100,
2
),
'%'
)
WHERE s_is_del = '1'
AND mn_project_management.project_no = {{Table2.triggeredRow.project_no}}
规则 21 · GROUP_CONCAT(crystallize+annotate)
- unique_key:
COC|DB|Mysql1378Copy1Copy1 - plugin_type / action_name_en:
DB/Mysql1378Copy1Copy1 - need_update:
1(选取=match_rule)
改前(截取)
SELECT
(SELECT CONCAT(''', GROUP_CONCAT(name SEPARATOR '', ''), ''')
FROM (
SELECT '客户转介绍' AS name UNION ALL
SELECT '线上拓展' UNION ALL
SELECT '线下拓展' UNION ALL
SELECT '自然门诊' UNION ALL
SELECT '内部引流'
UNION ALL
SELECT dict_data_name AS name
FROM opt_dict_data
WHERE dict_type_no =…
改后(截取)
SELECT
(SELECT CONCAT(''', STRING_AGG(name SEPARATOR '', '', ','), ''')
FROM (
SELECT '客户转介绍' AS name UNION ALL
SELECT '线上拓展' UNION ALL
SELECT '线下拓展' UNION ALL
SELECT '自然门诊' UNION ALL
SELECT '内部引流'
UNION ALL
SELECT dict_data_name AS name…
规则 22 · FIND_IN_SET(regex)
本批未命中,无 unique_key。
规则 23 · SUBSTRING_INDEX(regex)
本批未命中,无 unique_key。
规则 24 · LOCATE(regex)
本批未命中,无 unique_key。
规则 25 · LENGTH / CHAR_LENGTH(annotate)
- unique_key:
COC|DB|Mysql1179 - plugin_type / action_name_en:
DB/Mysql1179 - need_update:
0(选取=match_rule)
改前(截取)
…WHERE s_is_del = 1
ORDER BY
CASE
WHEN LENGTH(category_code) = 1 THEN 1 -- 一级分类
WHEN LENGTH(category_code) = 2 THEN 2 -- 二级分类
WHEN LENGTH(category_code) = 4 THEN 3 -- 三级分类
END ASC,
category_code ASC;
-- 按照商品分类SQL的格式(按特定类别置顶排序)
SELECT category_code, category_name, parent_id
FROM mn_asset_category
WHERE s_is_del = 1
ORDER BY
CASE
WHEN categ…
改后(截取)
…WHERE s_is_del = 1
ORDER BY
CASE
WHEN LENGTH(category_code) = 1 THEN 1 -- 一级分类
WHEN LENGTH(category_code) = 2 THEN 2 -- 二级分类
WHEN LENGTH(category_code) = 4 THEN 3 -- 三级分类
END ASC,
category_code ASC;
-- 按照商品分类SQL的格式(按特定类别置顶排序)
SELECT category_code, category_name, parent_id
FROM mn_asset_category
WHERE s_is_del = 1
ORDER BY
CASE
WHEN categ…
(annotate 或未改写:from=to)
规则 26 · 正则(regex)
本批未命中,无 unique_key。
规则 27 · CAST UNSIGNED(regex)
本批未命中,无 unique_key。
规则 28 · CONVERT → CAST(regex)
本批未命中,无 unique_key。
规则 29 · UUID(regex)
本批未命中,无 unique_key。
规则 30 · NOW(regex)
本批未命中,无 unique_key。
规则 31 · DATE_FORMAT(regex)
- unique_key:
COC|DB|Mysql1223Copy2Copy1Copy1Copy1 - plugin_type / action_name_en:
DB/Mysql1223Copy2Copy1Copy1Copy1 - need_update:
1(选取=match_rule)
改前(截取)
…nt_visit_detail
WHERE
order_time >= DATE_FORMAT(DATE_SUB(CURRENT_DATE, INTERVAL 1 YEAR), '%Y-01-01')
AND order_time < DATE_FORMAT(CURRENT_DATE, '%Y-01-01')
AND status IN ('3', '4', '5')
AND actual_pay_money IS NOT NULL
AND user_id IS NOT NULL
AND level2_category IN ('385', '26', '24', '22', '200', '139', '1000', '656', '370',…
改后(截取)
SELECT
ROUND(CAST(CAST(CAST(CAST(CAST(COALESCE(SUM(CASE WHEN mth = 1 THEN net_amount END AS numeric AS numeric AS numeric AS numeric AS numeric)))))), 0)
/ NULLIF(COUNT(DISTINCT CASE WHEN mth = 1 THEN user_id END), 0),
2
) AS 一月,
ROUND(CAST(CAST(CAST(CAST(CAST(COALESCE(SUM(CASE WHEN mth = 2 THEN net_amoun…
规则 32 · STR_TO_DATE(regex)
本批未命中,无 unique_key。
规则 33 · UNIX_TIMESTAMP(regex)
本批未命中,无 unique_key。
规则 34 · FROM_UNIXTIME(regex)
本批未命中,无 unique_key。
规则 35 · DATE_ADD(regex)
- unique_key:
COC|DB|Mysql1290 - plugin_type / action_name_en:
DB/Mysql1290 - need_update:
1(选取=match_rule)
改前(截取)
…TE) DAY) AS DATETIME) AS start_time,
CONCAT(DATE_ADD(DATE_SUB(CURRENT_DATE, INTERVAL WEEKDAY(CURRENT_DATE) DAY), INTERVAL 6 DAY), ' 23:59:59') AS end_time
)
SELECT
MAX(dr.start_time) AS 本周开始时间,
MAX(dr.end_time) AS 本周结束时间,
COUNT(CASE WHEN status = '1' THEN follow_id END) AS 已完成随访数,
COUNT(CASE WHEN status IN ('0','1','3') THEN follow_id END) AS 应回访总数,
CONCAT(ROUN…
改后(截取)
…) AS 应回访总数,
CONCAT(ROUND(CAST(CAST(CAST(CAST(CAST(COUNT(CASE WHEN status = '1' THEN follow_id END AS numeric AS numeric AS numeric AS numeric AS numeric))))))
/
NULLIF(COUNT(CASE WHEN status IN ('0','1','3') THEN follow_id END), 0)
* 100, 2), '') AS 随访完成率
FROM mn_member_follow_tickets
CROSS JOIN date_ranges…
规则 36 · DATEDIFF(regex)
本批未命中,无 unique_key。
规则 37 · DATE()(regex)
本批未命中,无 unique_key。
规则 38 · YEAR/MONTH(regex)
- unique_key:
COC|DB|Mysql1290Copy1Copy1Copy1Copy1Copy1Copy1 - plugin_type / action_name_en:
DB/Mysql1290Copy1Copy1Copy1Copy1Copy1Copy1 - need_update:
1(选取=match_rule)
改前(截取)
…12
),
monthly_register AS (
SELECT
MONTH(registered_time) AS month_num,
COUNT(DISTINCT user_id) AS total_num
FROM mn_daily_registered
WHERE
stores IN ({{deptD.text}})
AND s_is_del = 1
AND status IN ('1','3')
AND EXTRACT(YEAR FROM registered_time) = EXTRACT(YEAR FROM CURRENT_DATE)
GROUP BY MONTH(registered_ti…
改后(截取)
…CONCAT(
ROUND(CAST(CAST(CAST(CAST(CAST(COALESCE(a.arrived_num AS numeric AS numeric AS numeric AS numeric AS numeric))))), 0) / NULLIF(COALESCE(r.total_num, 0), 0) * 100,
2
),
''
) AS 月小程序到诊率
FROM months m
LEFT JOIN monthly_register r ON m.month_num = r.month_num
LEFT JOIN m…
规则 39 · CURDATE(regex)
本批未命中,无 unique_key。
规则 40 · JSON path(annotate)
- unique_key:
COC|DB|Mysql1101 - plugin_type / action_name_en:
DB/Mysql1101 - need_update:
1(选取=match_rule)
改前(截取)
…lass = 'A'
AND JSON_UNQUOTE(JSON_EXTRACT(c.change_history, '$[last].old_class')) != 'A'
AND JSON_UNQUOTE(JSON_EXTRACT(c.change_history, '$[last].change_reason')) ILIKE '升级%'
THEN 1 END) AS A_upgrade_count,
-- A类降级:当前不是A,最近一次变更从A降级
COUNT(CASE WHEN c.current_class != 'A'
AND JSON_U…
改后(截取)
…B_count AS C转B数量,
ROUND(CAST(CAST(CAST(CAST(CAST(cs.C_to_B_count * 100.0 / NULLIF(cc.C_count AS numeric AS numeric AS numeric AS numeric AS numeric))))), 0), 2) AS 一级转化率,
cs.B_to_A_count AS B转A数量,
ROUND(CAST(CAST(CAST(CAST(CAST(cs.B_to_A_count * 100.0 / NULLIF(cc.B_count AS numeric AS numeric AS numeric AS…
规则 41 · ON DUPLICATE KEY(annotate)
- unique_key:
COC|DB|MysqlPlus41 - plugin_type / action_name_en:
DB/MysqlPlus41 - need_update:
1(选取=match_rule)
改前(截取)
…ame},#{item.suppliers_commodity_id})
</foreach>
ON DUPLICATE KEY UPDATE
s_is_del=1
改后(截取)
…--{item.commodity_name},--{item.suppliers_name},--{item.suppliers_commodity_name},#{item.suppliers_commodity_id})
</foreach>
ON DUPLICATE KEY UPDATE
s_is_del=1
规则 42 · new_row 别名(regex)
本批未命中,无 unique_key。
规则 43 · INSERT IGNORE(annotate)
- unique_key:
COC|DB|Mysql1114 - plugin_type / action_name_en:
DB/Mysql1114 - need_update:
0(选取=match_rule)
改前(截取)
INSERT IGNORE INTO mn_fixed_assets_in (
in_order_no,
in_type,
in_date,
in_department_name,
in_department_id,
handler_department,
handler,
handler_id,
s_create_time,
s_create_by,
remark,
total_quantity,
total_amount,
purchaser,
purchase_date
)
VALUES
(
'{{global.store.CURRENT_TRANSFER_ORDER_NO}}',
'…
改后(截取)
INSERT IGNORE INTO mn_fixed_assets_in (
in_order_no,
in_type,
in_date,
in_department_name,
in_department_id,
handler_department,
handler,
handler_id,
s_create_time,
s_create_by,
remark,
total_quantity,
total_amount,
purchaser,
purchase_date
)
VALUES
(
'{{global.store.CURRENT_TRANSFER_ORDER_NO}}',
'…
(annotate 或未改写:from=to)
规则 44 · REPLACE INTO(annotate)
本批未命中,无 unique_key。
规则 45 · UPDATE JOIN(annotate)
- unique_key:
COC|DB|receptionMedicalDiseaseEntryU - plugin_type / action_name_en:
DB/receptionMedicalDiseaseEntryU - need_update:
0(选取=match_rule)
改前(截取)
update mn_basis_disease_entry set disease_code={{uDiseaseCode.selectedOptionValues.join(',')}},entry_name={{uEntryName.text}} where entry_code={{Table1.triggeredRow.entry_code}}
改后(截取)
update mn_basis_disease_entry set disease_code={{uDiseaseCode.selectedOptionValues.join(',')}},entry_name={{uEntryName.text}} where entry_code={{Table1.triggeredRow.entry_code}}
(annotate 或未改写:from=to)
规则 46 · DELETE JOIN(annotate)
本批未命中,无 unique_key。
规则 47 · 多表 DELETE(annotate)
本批未命中,无 unique_key。
规则 48 · 取自增 ID(annotate)
本批未命中,无 unique_key。
规则 49 · 松散 GROUP BY(annotate)
- unique_key:
COC|DB|Mysql1290Copy1Copy1Copy1Copy1 - plugin_type / action_name_en:
DB/Mysql1290Copy1Copy1Copy1Copy1 - need_update:
1(选取=match_rule)
改前(截取)
….s_is_del = 1
AND u.customer_type = 4
GROUP BY u.user_id
),
lost_customer AS (
SELECT
COUNT(DISTINCT user_id) AS lost_num
FROM customer_last_register
CROSS JOIN date_ranges dr
WHERE last_reg_time < dr.two_years_ago
OR last_reg_time IS NULL
)
SELECT
dr.two_years_ago AS 流失判定临界时间(精确),
t.total_num AS 总老客户数,
l.lost_num AS 流失老…
改后(截取)
…,
CONCAT(
ROUND(CAST(CAST(CAST(CAST(CAST(l.lost_num / NULLIF(t.total_num AS numeric AS numeric AS numeric AS numeric AS numeric))))), 0) * 100, 2),
''
) AS 客户流失率
FROM total_old_customer t
CROSS JOIN lost_customer l
CROSS JOIN date_ranges dr;
规则 50 · 隐式类型转换(regex)
本批未命中,无 unique_key。
规则 51 · 除法(annotate)
- unique_key:
COC|DB|Mysql1371 - plugin_type / action_name_en:
DB/Mysql1371 - need_update:
1(选取=match_rule)
改前(截取)
…type_id = mc.commodity_type_id
),
-- 本期挂号人数:到店(1/3)、成交(3/5)
curr_register AS (
SELECT
COUNT(DISTINCT CASE WHEN t1.status IN ('1' THEN '3') ELSE t1.user_id, NULL END) AS arrive_people,
COUNT(DISTINCT CASE WHEN t1.status IN ('3' THEN '5') ELSE t1.user_id, NULL END) AS deal_people
FROM params p
JOIN mn_daily_registered t1
ON t1.s_is…
改后(截取)
…(
SELECT
ROUND(CAST(CAST(CAST(CAST(CAST(revenue / NULLIF(unique_users AS numeric AS numeric AS numeric AS numeric AS numeric))))), 0), 2) AS 本期客单价,
ROUND(CAST(CAST(CAST(CAST(CAST(revenue_yoy / NULLIF(unique_users_yoy AS numeric AS numeric AS numeric AS numeric AS numeric))))), 0), 2) AS 去年同期客单价…
规则 52 · ROUND 需 numeric(regex)
- unique_key:
COC|DB|Mysql1007 - plugin_type / action_name_en:
DB/Mysql1007 - need_update:
1(选取=match_rule)
改前(截取)
…t_management
SET project_progress = CONCAT(
ROUND(CAST(CAST(CAST(CAST((project_endSteps / progress_total AS numeric AS numeric AS numeric AS numeric))))) * 100,
2
),
'%'
)
WHERE s_is_del = '1'
AND mn_project_management.project_no = {{Table2.triggeredRow.project_no}}
改后(截取)
…rogress = CONCAT(
ROUND(CAST(CAST(CAST(CAST(CAST((project_endSteps / progress_total AS numeric AS numeric AS numeric AS numeric AS numeric)))))) * 100,
2
),
'%'
)
WHERE s_is_del = '1'
AND mn_project_management.project_no = {{Table2.triggeredRow.project_no}}
规则 53 · 事务中止 25P02(annotate)
本批未命中,无 unique_key。
规则 54 · smallint = boolean(annotate)
- unique_key:
COC|DB|Mysql1056 - plugin_type / action_name_en:
DB/Mysql1056 - need_update:
0(选取=match_rule)
改前(截取)
…st/design/COC/actions/queries/Mysql1055?editName=true&showTemplate=true&from=datasources
改后(截取)
…st/design/COC/actions/queries/Mysql1055?editName=true&showTemplate=true&from=datasources
(annotate 或未改写:from=to)
规则 C1 · SQL_CALC_FOUND_ROWS / FOUND_ROWS(crystallize)
本批未命中,无 unique_key。
规则 C2 · JSON_OBJECTAGG(crystallize)
本批未命中,无 unique_key。