4.6 对位序列
对于已经序号化的维表,可以利用对位序列来处理维表上的过滤。
原理:产生一个与维表同样长度的序列,其成员是布尔值,满足条件的维表记录对应 true,否则对应 false。然后在事实表中用已经序号化的外键作为位置取出这个对位序列的相应成员,就能判断出该维表记录是否已经被过滤,快速决定是否把事实表记录也过滤掉。
因为不需要做实质性的查找,对位序列的性能非常好,在处理维表过滤时很有效。
SQL
SELECT sum(Amount)
FROM Orders
WHERE OrderDate>='2021-01-01' and OrderDate<='2021-12-31' and EmployeeID not in (
SELECT EmployeeID
FROM Employee
WHERE Employees.Country='USA')
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() |
3 | =Employees.(Country!=“USA”) |
4 | =file(“Orders_Time.ctx”).open().cursor@mx(Amount;OrderDate>=start && OrderDate<=end && A3(EmployeeID)) |
5 | =A4.groups(;sum(Amount)) |
A3 计算维表对应的 boolean 序列,表示当前成员是否满足 Country=="USA" 的过滤条件
A4 在组表游标中用序号和 A3 关联,只保留 A3 为 true 的记录
SQL
SELECT a.EmployeeID,concat(a.FirstName,' ', a.LastName) EmployeeName,
sum(Amount) Amount
FROM Orders
INNER JOIN (
SELECT *
FROM Employees
WHERE Employees.Country<>'USA'
) a ON Orders.EmployeeID=a.EmployeeID
WHERE OrderDate>='2021-01-01' and OrderDate<='2021-12-31'
GROUP BY a.EmployeeID,a.FirstName+' '+ a.LastName
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().derive(FirstName+" "+LastName:EmployeeName) |
3 | =Employees.(if(Country!=“USA”,~,null)) |
4 | =file(“Orders_Time.ctx”).open().cursor@mx(EmployeeID,Amount;OrderDate>=start && OrderDate<=end,EmployeeID:A3:#) |
5 | =A4.groups(EmployeeID.EmployeeID;EmployeeID.EmployeeName,sum(Amount):Amount) |
A3 计算维表对位序列的变种,不满足条件的位置置为 null,满足条件的位置为原记录
A4 在组表游标中用序号和 A3 关联,只保留 A3 不为 null 的记录,关联后组表的 EmployeeID 字段是对应 A3 的成员,可以在后续计算中引用
A5 引用 EmployeeID 里的字段值进行统计