4.1 维表内存化
4.1.1 单层维表
SQL
SELECT Employees.Region,sum(Orders.Amount)
FROM Orders
LEFT JOIN Employees ON Orders.EmployeeID=Employees.EmployeeID
WHERE OrderDate>='2021-01-01' and OrderDate<='2021-12-31'
GROUP BY Employees.Region
SPL
A | |
---|---|
1 | >st=date(“2021-01-01”), et=date(“2021-12-31”), start=days@o(st), end=days@o(et) |
2 | >Employees=file(“Employees.btx”).import@b().keys@i(EmployeeID) |
3 | =file(“Orders_Time.ctx”).open().cursor@mx(EmployeeID,Amount;OrderDate>=start && OrderDate<=end) |
4 | =A3.switch(EmployeeID,Employees:EmployeeID) |
5 | =A4.groups(EmployeeID.Region;sum(Amount):Amount) |
A2 从集文件 Employees.btx 中读取维表数据至内存,设置主键并建立索引
A4 将 A3 游标关联内存中的维表 Employees
A5 对关联之后的游标 A3,做小结果集分组计算
用 switch() 关联维表时,需要事先在维表上设置主键,利用维表主键关联。关联后,将把事实表关联字段取值转换为维表记录的引用,之后可以用 "事实表字段. 维表字段" 的方式引用维表中的任意一个字段。
维表经常被复用,而且通常维表不大,可以事先装入内存并建立主键索引,用全局变量保存,之后在统计时不用再读维表及建立主键索引了,直接使用全局变量即可。这样相当于把上述代码拆成两段,一段在服务器启动时把维表装载进全局变量,另一段则是统计代码:
第一段代码 (服务器启动时执行一次即可):
A | |
---|---|
1 | >env(Employees, file(“Employees.btx”).import@b().keys@i(EmployeeID)) |
第二段代码 (统计部分):
A | |
---|---|
1 | >st=date(“2021-01-01”), et=date(“2021-12-31”), start=days@o(st), end=days@o(et) |
2 | =file(“Orders_Time.ctx”).open().cursor@mx(EmployeeID,Amount;OrderDate>=start && OrderDate<=end) |
3 | =A2.switch(EmployeeID,Employees:EmployeeID) |
4 | =A3.groups(EmployeeID.Region;sum(Amount):Amount) |
4.1.2 多层维表预关联
SQL
SELECT Suppliers.Region,sum(Orders.Quantity* Orders.Price)
FROM Orders
LEFT JOIN Products ON Orders.ProductID= Products.ProductID
LEFT JOIN Suppliers ON Products.SupplierID=Suppliers.SupplierID
WHERE OrderDate>='2021-01-01' and OrderDate<='2021-12-31'
GROUP BY Suppliers.Region
SPL
多层维表,也在服务器启动时一次性读入内存,存成全局变量,并建立主键索引和维表之间的关联关系
A | |
---|---|
1 | >env(Suppliers,file(“Suppliers.btx”).import@b().keys@i(SupplierID)) |
2 | >env(Products,file(“Products.btx”).import@b().keys@i(ProductID)) |
3 | >Products.switch(SupplierID, Suppliers:SupplierID) |
A1 读入供应商维表,建立主键索引
A2 读入产品维表,建立主键索引
A3 将 Products 和 Suppliers 建立关联
统计时直接使用:
A | |
---|---|
1 | >st=date(“2021-01-01”), et=date(“2021-12-31”), start= days@o(st), end=days@o(et) |
2 | =file(“Orders_Time.ctx”).open().cursor@mx(ProductID,Quantity,Price;OrderDate>=start && OrderDate<=end) |
3 | =A2.switch(ProductID,Products:ProductID) |
4 | =A3.groups(ProductID.SupplierID.Region;sum(Quantity*Price):Amount) |
A3 将 A2 游标关联内存中的维表 Products
A4 对关联之后的游标 A3,做小结果集分组计算
本例为多级维表,Orders 表 -Products 表 -Suppliers 表,可以用. 操作符逐级引用,比如 "ProductID.SupplierID.Region" 表示从 Orders 表的 ProductID 字段引用关联维表中的 SupplierID 字段再引用该字段关联维表中的 Region。