基于宏变量的元编程
宏变量
宏变量在元编程中提供了一种更加简单和直观的方法。在 SQL 元代码中,根据变量定义的列是单列还是多列,动态获取宏变量的方式也会有所不同。
-
单列宏变量:指为变量赋值了表中一个列的字段名称,使用 “_$“ 符号来动态获取该变量的值。例如,变量定义为
name="sym"
,元代码可写为<SELECT _$name FROM t>
,在执行时会替换为SELECT sym FROM t
。 -
多列宏变量:指为变量赋值了表中多个字段的名称,使用 “_$$“ 符号来动态获取该变量中的多个值。例如,变量定义为
names=["sym", "time"]
,元代码可写为<SELECT _$$name FROM t>
,在执行时会替换为SELECT sym, time FROM t
。
使用宏变量相较于函数生成的元代码,可以让脚本更加简洁和易于理解。然而,宏变量的使用也存在一些限制:
-
变量名类型必须是 STRING,且变量值需要符合 DolphinDB 数据表字段的命名规范,即不能以数字和符号开头。
-
宏变量仅能用于 SELECT,WHERE,GROUP BY,PIVOT BY,CONTEXT BY,CSORT,ORDER BY 等子句。不能用于 FROM 子查询、UPDATE、DELETE 和 OVER 语句。而且在 CSORT 和 ORDER BY 子句中只能使用 “_$“,不能使用 “_$$“。以 FROM 子查询为例,不支持类似这种写法
<select * from select _$$names1 from t>
。 -
宏变量只能在列定义(包括获取列名和定义别名)、函数和表达式中使用。在函数或表达式中应用多列宏变量时,相当于提供了一个元组,其中每个元素对应一列。
例子
t = table(take(2023.01M+1 2 1 1 2,5) as month, take(`Rome`London`London`Rome,5) as city, take(200 500 100 300 300, 5) as sold1, take(2100 1500 1100 3100 2300,5) as sold2)
selectCity="city"
<select _$selectCity from t>.eval()
city |
---|
Rome |
London |
London |
Rome |
Rome |
selectCity="city"
selectSold1="sold1"
alias="avg_sold1"
<select avg(_$selectSold1) as _$alias from t group by _$selectCity>.eval()
city | avg_sold1 |
---|---|
Rome | 266.6667 |
London | 300 |
在元代码中通过 “_$$“ 查询表中的多个列:
colNames=["city", "sold1"]
<select _$$colNames from t>.eval()
city | sold1 |
---|---|
Rome | 200 |
London | 500 |
London | 100 |
Rome | 300 |
Rome | 300 |
colNames=["sold1", "sold2"]
alias = "sum_sold"
<select rowSum(_$$colNames) as _$alias from t>.eval()
sum_sold |
---|
2,300 |
2,000 |
1,200 |
3,400 |
2,600 |
高阶函数中使用多列宏变量:上例也可通过高阶函数实现对表中的列 sold1 和 sold2 按行应用 sum 函数。
<select sum:H(_$$colNames) as _$alias from t>.eval()
sum_sold |
---|
2,300 |
2,000 |
1,200 |
3,400 |
2,600 |
colNames=["sold1", "sold2"]
alias=["sum_sold1", "sum_sold2"]
<select sum:V(_$$colNames) as _$$alias from t>.eval()
sum_sold1 | sum_sold2 |
---|---|
1,400 | 10,100 |