王大锤

少年,我看你骨骼精奇,是万中无一的武学奇才,维护世界和平就靠你了!

18篇博客

LOD算法其一:fixed的含义及其用法

王大锤2020-08-13 14:05

LOD算法的全称是详细级别表达式(level of detail expressisons)。它主要是为了克服一些表达式之间的算子粒度不一致的问题。例如,我们在回答一个简单的问题的时候:我想知道每个人的身高与平均身高之间的差别。通常,为了得到结果,我们需要进行两步查询,第一步,查出所有人的平均身高:SELECT AVG(height) FROM humans ,假设该值为H; 第二步,将每个人的身高减去这个平均值: SELECT height - H FROM humans;

这是一个两步的过程,如果想使用一个表达式完成这个查询该怎么做呢?它的过程就会比较复杂:

      SELECT all.height - avg.H 

      FROM humans as all 

      JOIN (SELECT AVG(height) as H FROM humans) as avg

      而LOD就是相当于实现了后者的过程,以便用户在一个简单的表达式内就简单的可以实现这个需求: [身高]- {FIXED : AVG([身高])}

      详细级别表达式可以解答非常多这类的问题,比如单日销售额和月总计销售额的占比如何,总售出超过100万元的产品是来自哪些订单……凡是明细粒度和聚合粒度不一致,但是却又需要比较的场景,我们都可以通过LOD简单的实现。

再举一个例子,有数的表格如下

浙江 杭州 100
浙江 宁波 150
江苏 南京 200
江苏 苏州 150

如上图,假设我们需要求省级别的总和,我们只需要做成如下

浙江 250
江苏 350

那如果我们需要做成

浙江 杭州 100 本省之和(250)
浙江 宁波 150 本省之和(250)
江苏 南京 200 本省之和(350)
江苏 苏州 150 本省之和(350)

该如何实现这个本省之和呢?

这就引入fixed做跨粒度计算,本省之和= {FIXED [省份]:SUM(额度)}

这样就相当于在省份的粒度上对额度求和了。这样也就容易计算各城市额度占省份之比等各类指标。

扩展阅读1:

假设我在省份的面前加上一个日期维度:

2019-8-1 浙江 杭州 100 {FIXED [省份]:sum(额度)}  =450
2019-8-1 浙江 宁波 150 {FIXED [省份]:sum(额度)} =450
2019-8-2 浙江 杭州 200 {FIXED [省份]:sum(额度)} =450
2019-8-1 江苏 南京 200 {FIXED [省份]:sum(额度)} =200

可以看到这里的维度其实是不对了,因为我们要求杭州在8-1号的省占比,其实应该是100/(100+150)而不是100/(100+150+200)。

所以此时需要将计算字段改为{FIXED [日期],[省份]:SUM(额度)};

扩展阅读2:

由于fixed语法其实是利用了一个子查询,如

 SELECT all.height - avg.H 

      FROM humans as all 

      JOIN (SELECT AVG(height) as H FROM humans) as avg

那么如果我在界面上添加了一个过滤器比如 性别筛选器=男,那么这个查询会变成什么样呢?如下:

SQL1:

 SELECT all.height - avg.H 

      FROM humans where  SEX="男" as all 

      JOIN (SELECT AVG(height) as H FROM humans) as avg

但其实我们需要求男性平均身高差其实应该是

SQL2:

 SELECT all.height - avg.H 

      FROM humans where  SEX="男" as all 

      JOIN (SELECT AVG(height) as H FROM humans where  SEX="男" ) as avg

这个时候就需要将我们的性别筛选器的优先级提升,勾选其“优先筛选”才可以做到SQL2的效果。