11 KiB
TSL TS-SQL
文档类型:语法主线 是否可直接用于生成代码:是 是否含可直接照写示例:是 是否含不可照写反例:是 遇到不确定时:先按本页候选页继续判断;13_resultset_and_filters.md、12_matrix_and_collections.md、23_fmarray.md;仍不命中时回到语法路由中心 index.md;如果问题已经超出语法层,回到 TSL 总入口 ../index.md
这一篇是 TS-SQL 的唯一语法入口:内存数组查询、返回形态、字段访问、where / group by / order by、一维数组查询、多表 join、thisGroup、thisRowIndex、refMaxOf / refMinOf 都在这里收拢。
本篇职责
回答“写 TS-SQL 查询时,怎样从最小 select ... from ... end 骨架开始,逐步处理筛选、分组、排序、多表联接、组内子查询和极值引用”。
智能体 TS-SQL 判断流程
- 先判断要写
select、sselect、vselect、mselect,还是join/thisGroup/ 极值引用。 - 内存数组查询优先从
select ... from source_rows end最小骨架起手。 - 二维结果集字段访问用
["字段名"];多表查询字段访问用[表序号].["字段名"]。 - 在一维数组上做 TS-SQL 时,优先使用
thisRow和thisRowIndex。 - 只想按已有结果集保留/排除行时跳到 13_resultset_and_filters.md;要做去重型集合关系时跳到 12_matrix_and_collections.md;要在
FMArray上做查询或写回边界时跳到 23_fmarray.md。 - 没有对应代码块时不要发明 TS-SQL 写法。
核心规则
- TS-SQL 是 TSL 自带的类 SQL 查询语法,不是金融业务函数库。
- 基础查询文档骨架是:以
select/sselect/vselect/mselect开始,以end收尾。 from后面可以直接跟内存数组结果集。- 在内存二维结果集上,文档字段访问写法是
["字段名"]。 - 在一维数组上做 TS-SQL 时,优先使用
thisRow和thisRowIndex。 select返回二维结果,sselect返回一维结果,vselect返回单值,mselect返回Matrix。where、group by、order by可以直接接在from后面继续使用。- 多表
join时,字段访问应写成[表序号].["字段名"]。 thisGroup不是普通值,而是分组后的子结果集;要通过子select/vselect的from thisGroup来访问。thisRowIndex在order by之后仍可返回原始行位置,而不是排序后的序号。refMaxOf(...)和refMinOf(...)可与maxOf(...)/minOf(...)配合,取极值所在行的另一列值。- 访问金融表、时间序列或业务数据源时,语法和业务语义要分开看;本页只讲语言层查询骨架。
可直接照写示例
最小查询骨架
代码块身份:可直接照写示例
source_rows := array(
("A": 1, "B": 3),
("A": 2, "B": 1)
);
query_result := select * from source_rows end;
writeLn(length(query_result));
结果说明:
query_result的长度是2- 两行依次是
(1,3)、(2,1) - 说明 TS-SQL 的最短可靠入口就是“准备结果集,然后
select ... from source_rows end”
代码块身份:输出片段
2
字段选择
代码块身份:可直接照写示例
source_rows := array(
("A": 1, "B": 3),
("A": 2, "B": 1),
("A": 1, "B": 2)
);
query_result := select ["A"], ["B"] from source_rows end;
writeLn(length(query_result));
结果说明:
query_result的长度是3- 三行依次是
(1,3)、(2,1)、(1,2) - 说明
select ["A"], ["B"] from source_rows end会按原顺序返回二维结果集
四个查询入口怎样分工
代码块身份:可直接照写示例
source_rows := array(
("A": 1, "B": 3),
("A": 2, "B": 1),
("A": 1, "B": 2)
);
selected_values := sselect ["A"] from source_rows end;
sum_value := vselect sumOf(["B"]) from source_rows end;
matrix_result := mselect * from source_rows end;
col_index := mcols(matrix_result, 1);
结果说明:
sselect ["A"] from source_rows end返回一维数组array(1, 2, 1)vselect sumOf(["B"]) from source_rows end返回单值6mselect * from source_rows end的行数是3、列数是2mcols(matrix_result, 1)返回列索引array("A", "B")- 本页只把
mselect的“返回 Matrix 且保留行列信息”写成文档主干;不要在本页发明直接单元格读取规则
where 和 order by
代码块身份:可直接照写示例
source_rows := array(
("A": 1, "B": 3),
("A": 2, "B": 1),
("A": 1, "B": 2)
);
query_result := select * from source_rows where ["B"] > 1 order by ["B"] end;
结果说明:
query_result的长度是2- 两行依次是
(1,2)、(1,3) - 说明
where ["B"] > 1会先筛选,再按order by ["B"]的升序返回
group by
代码块身份:可直接照写示例
source_rows := array(
("A": 1, "B": 3),
("A": 2, "B": 1),
("A": 1, "B": 2)
);
group_result := select ["A"], sumOf(["B"]) as "SumB"
from source_rows
group by ["A"]
order by ["A"]
end;
结果说明:
group_result的长度是2- 第一行是
(1,5) - 第二行是
(2,1) - 说明
group by ["A"]后可以直接接聚集函数,并用as "SumB"指定返回列名
一维数组上的 thisRow 与 thisRowIndex
代码块身份:可直接照写示例
values := array(10, 20, 30);
row_values := sselect thisRow from values end;
row_indexes := sselect thisRowIndex from values end;
query_result := select thisRow as "Value", thisRowIndex as "Idx"
from values
where thisRow > 15
order by thisRow
end;
结果说明:
sselect thisRow from values end返回array(10, 20, 30)sselect thisRowIndex from values end返回array(0, 1, 2)- 上面的
select ... from values where thisRow > 15 order by thisRow end返回两行:第一行Value=20, Idx=1,第二行Value=30, Idx=2
join
代码块身份:可直接照写示例
left_rows := array(
("ID": 1, "V1": 10),
("ID": 2, "V1": 20)
);
right_rows := array(
("ID": 1, "V2": 100),
("ID": 3, "V2": 300)
);
join_result := select [1].["ID"], [1].["V1"], [2].["V2"]
from left_rows join right_rows on [1].["ID"] = [2].["ID"]
end;
writeLn(length(join_result));
writeLn(join_result[0]["ID"]);
writeLn(join_result[0]["V1"]);
writeLn(join_result[0]["V2"]);
结果说明:
join_result的长度是1- 唯一一行是
(1,10,100) - 说明
from left_rows join right_rows on ...和[1].["字段"]、[2].["字段"]这种多表字段访问属于文档明确写法
代码块身份:输出片段
1
1
10
100
thisGroup
代码块身份:可直接照写示例
source_rows := array(
("A": 1, "B": 3, "Name": "x"),
("A": 2, "B": 1, "Name": "y"),
("A": 1, "B": 2, "Name": "z")
);
group_result := select ["A"], maxb := maxOf(["B"]) as "MaxB",
vselect ["Name"] from thisGroup where ["B"] = maxb end as "TopName"
from source_rows
group by ["A"]
order by ["A"]
end;
结果说明:
group_result的长度是2- 第一行是
(1,3,"x") - 第二行是
(2,1,"y") - 说明
thisGroup可以在分组上下文里作为子结果集继续vselect
thisRowIndex 在排序后仍指向原始位置
代码块身份:可直接照写示例
source_rows := array(
("A": 1, "B": 3),
("A": 2, "B": 1),
("A": 1, "B": 2)
);
query_result := select thisRowIndex as "Idx", ["B"]
from source_rows
order by ["B"]
end;
结果说明:
query_result的三行依次是(1,1)、(2,2)、(0,3)- 说明
order by ["B"]之后,thisRowIndex仍返回原表中的原始下标
refMaxOf 与 refMinOf
代码块身份:可直接照写示例
source_rows := array((6, 20), (5, 20), (9, 2), (2, 20), (7, 18));
max_ref_result := select maxOf([0]) as "MaxA", refMaxOf([1]) as "RefB" from source_rows end;
min_ref_result := select minOf([0]) as "MinA", refMinOf([1]) as "RefB" from source_rows end;
结果说明:
max_ref_result只有一行,结果是(9,2)min_ref_result只有一行,结果是(2,20)- 说明
refMaxOf([1])取到了[0]最大值所在行的[1],refMinOf([1])取到了[0]最小值所在行的[1]
本页不生成的范围
with onleft join/right join/full joinRefsOfinsert/update/deleteTSQLInsert/TSQLSetValue/TSQLBatchInsertTSQLEdit/TSQLPost/TSQLFinal- 面向 SQL 表、业务表或时间序列的数据查询与写回
这些内容不作为本页可生成事实;业务数据源先查 ../reference/catalog/datawarehouse.md、../modules/pytsl_api.md 或项目实际接口。
默认生成模板
TS-SQL 的最短默认骨架如下:
代码块身份:可直接照写示例
query_result := select * from source_rows end;
禁止项
- 不要把数据库 SQL 方言直接迁移成 TS-SQL 代码。
- 不要把
select当成普通函数调用,忘了以end收尾。 - 在二维结果集里直接写
A而不是["A"]。 - 多表联接时继续写成
["ID"],没有加表序号。 - 处理一维数组时直接把
[0]当成稳定列访问。 - 把
thisGroup当成普通字段或普通变量。 - 把排序后的
thisRowIndex误当成排序序号。 - 把
with on、写回接口和时间序列缓存写进默认模板。
代码块身份:反例 / 不可照写
query_result := select A from source_rows end;
上面这种写法不要当成本页可靠规则。二维结果集字段访问,本页只把 ["A"] 这种写法写成文档主干。
代码块身份:反例 / 不可照写
query_result := select [0] from values end;
这种对一维数组直接用 [0] 的写法虽然返回长度为 3 的结果,但取到的值是 nil,不能当成可靠入口。对一维数组应改用 thisRow 和 thisRowIndex。
代码块身份:反例 / 不可照写
query_result := select ["ID"], ["V1"], ["V2"]
from left_rows join right_rows on ["ID"] = ["ID"]
end;
上面这种写法不要当成本页可靠规则。多表查询里,本页只把 [1].["字段"]、[2].["字段"] 这种带表序号的访问方式写成文档主干。
代码块身份:反例 / 不可照写
group_value := thisGroup;
不要把 thisGroup 当成普通值直接使用。可靠入口是 select ... from thisGroup end 或 vselect ... from thisGroup end。