基于宏变量的元编程

宏变量

宏变量在元编程中提供了一种更加简单和直观的方法。在 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
通过 “_$$“ 查询表中的多个列,并分别对每列应用相同的函数:下例对表中的列 sold1 和 sold2 分别应用了 sum 函数,计算每列的和。
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