7.19 带过滤条件的笛卡尔积
两个相互关联的表,获得它们的叉积后过滤计算。
根据三明治表和配料表,查询哪两种三明治的配料最接近。
Sandwich:
| ID | Name | Price |
|---|---|---|
| 1 | BLT | 5.5 |
| 2 | Reuben | 7.0 |
| 3 | Grilled Cheese | 3.75 |
Ingredient:
| ID | Ingredient |
|---|---|
| 1 | bacon |
| 1 | lettuce |
| 1 | tomato |
| … | … |
这里用到了 xjoin() 函数计算叉积。值得注意的是 SPL 叉积结果的记录是由两个表的记录组成,而不是简单的把所有字段展开。
脚本:
| A | |
|---|---|
| 1 | =connect(“db”) |
| 2 | =A1.query@x(“select i.ID ID, i.Ingredient Ingredient, s.Name Name from Sandwich s, Ingredient i where s.ID=i.ID order by ID”) |
| 3 | =A2.group@o(ID;Name,~.(Ingredient):Collection) |
| 4 | =xjoin(A3:A;A3:B,A.ID<ID) |
| 5 | =A4.new((A.Collection ^ B.Collection).len():Count, A.Name:Name1, B.Name:Name2).sort@z(Count) |
A1 连接数据库
A2 查询三明治表和配方表
A3 使用 group@o() 按 ID 归并分组,并将每种三明治配料存储在 Collection 字段
A4 使用 xjoin 函数将查询结果与自身计算叉积,并选出 ID 不同的组合
A5 计算两种配方有多少重复的配料,并按照重复数量降序排列。
运行结果:
| Count | Name1 | Name2 |
|---|---|---|
| 1 | Reuben | Grilled Cheese |
| 0 | BLT | Reuben |
| 0 | BLT | Grilled Cheese |
