设为首页 加入收藏

TOP

与SQL窗口函数相同
2018-12-12 04:08:42 】 浏览:65
Tags:SQL 窗口 函数 相同
窗口函数的目的是以声明的方式将业务报告需求转换为SQL,从而使查询性能和开发人员/业务分析师的效率得到显着提高。我看到现实世界的报告和仪表板在使用窗口功能后从几小时到几分钟,几分钟到几秒钟。查询大小从40页减少到几页。早在上世纪90年代,Redbrick 数据库就真正理解了业务用例并创建了一个新的功能层来进行业务报告,包括排名,运行总计,根据子组,位置等计算佣金和库存。这些都是在SQL标准中每个BI层(如Tableau,Looker,Cognos)都利用此功能。

窗口函数简介

想象一下,通过两轮比赛你有六个高尔夫球手。现在,您需要创建排行榜并对其进行排名。使用SQL对它们进行排名

播放机 第1轮 Round2

马尔科 75 73

约翰 72 68

常 67 76

宵 74 71

Sitaram 68 72

冰洁 71 67

将数据插入Couchbase。

INSERT INTO高尔夫

VALUES(“KP1”,{ “player”:“Marco”,“round1”:75,“round2”:73}),

VALUES(“KP2”,{ “player”:“Johan”,“round1”:72,“round2”:68}),

VALUES(“KP3”,{ “player”:“Chang”,“round1”:67,“round2”:76}),

VALUES(“KP4”,{ “player”:“Isha”,“round1”:74,“round2”:71}),

VALUES(“KP5”,{ “player”:“Sitaram”,“round1”:68,“round2”:72}),

VALUES(“KP6”,{ “玩家”:“冰洁”,“ROUND1”:71,“round2”:67});

没有窗口功能(当前状态 - Couchbase 6.0)

要在不使用窗口函数的情况下编写查询,您需要一个子查询来计算每个玩家的等级。该子查询必须扫描所有数据,导致O(N ^ 2)的最差算法复杂度,这大大增加了执行时间和吞吐量。

用g1 作为(选择球员,第1轮,第2轮从高尔夫球场)

SELECT g3 .player AS player,

(g3 .round 1 + g3 .round 2) AS T,

((g3 .round 1 + g3 .round 2) - 144) AS ToPar,

(选择原始1 + COUNT(*)

从 g1 作为 g2

其中(g2 .round 1 + g2 .round 2)<

(g3 .round 1 + g3 .round 2))[ 0 ] AS sqlrankR2

从 g1 到 g3

ORDER BY sqlrankR2

结果:

T ToPar播放器sqlrankR2

138 - 6 “冰洁” 1

140 - 4 “约翰” 2

140 - 4 “Sitaram” 2

143 - 1 “Chang” 4

145 1 “Isha” 5

148 4 “Marco” 6

使用Mad-Hatter中的窗口函数(即将发布)

此查询返回玩家,两轮后的总数(T),分数如何超过/低于标准(ToPar),然后根据前两轮的分数对它们进行排名。这是Mad-Hatter的新功能。其时间复杂度为O(N),意味着执行时间只会线性增加。

SELECT 播放器 AS播放器,

(round1 + round2) AS T,

((round1 + round2) - 144) AS ToPar,

RANK()OVER(ORDER BY(round1 + round2))AS rankR2

来自高尔夫;

T ToPar玩家等级R2

138 - 6 “冰洁” 1

140 - 4 “约翰” 2

140 - 4 “Sitaram” 2

143 - 1 “Chang” 4

145 1 “Isha” 5

148 4 “Marco” 6

观察:

查询简单明了地表达了要求。

在真实场景中执行此查询的效果要好得多。我们计划衡量。

当排名要求依赖于多个文档时,查询变得非常复杂 - 编写,优化和运行。

所有这些都会影响总体TCO。

现在,让我们创建一个扩展的仪表板。

显示添加密集排名,行号,领先者以及领导者背后的笔画数。报告中的所有非常常见的事情。只要看到OVER()子句,就会看到新的窗口函数。下面的查询有六个窗口函数。

SELECT 播放器 AS播放器,

(round1 + round2) AS T,

((round1 + round2) - 144) AS ToPar,

RANK()OVER(ORDER BY(round1 + round2))AS rankR2,

DENSE_RANK()OVER(ORDER BY(round1 + round2))AS rankR2Dense,

ROW_NUMBER()OVER()rownum,

((round1 + round2) -

FIRST_VALUE(ROUND1 + round2)

OVER(ORDER BY(round1 + round2)))AS strokebehind,

RANK()OVER(ORDER BY(round1)) AS rankR1,

LAG(播放器,1,“无”)OVER(ORDER BY ROUND1 + round2)

AS inFront

从高尔夫球场

ORDER BY rankR2

T ToPar inFront player rankR1 rankR2 rankR2Dense rownum stroke behind behind

138 - 6 “无” “冰洁” 3 1 1 3 0

140 - 4 “Johan” “Sitaram” 2 2 2 2 2

140 - 4 “冰洁” “约翰” 4 2 2 4 2

143 - 1 “Sitaram” “Chang” 1 4 3 1 5

145 1 “Chang” “Isha” 5 5 4 5 7

148 4 “Isha” “Marco” 6 6 5 6 10

正如您之前看到的,使用子查询方法使用六个窗口函数执行此查询将是一个更大的努力,昂贵,容易出错的查询。

除了将内置聚合(COUNT,SUM,AVG等)作为窗口函数,即将发布的版本将具有以下窗口函数。它们中的每一个的语法和语义在标准中得到很好的定义,并在下面的参考部分的文章中进行了充分描述。

RANK()

DENSE_RANK()

PERCENT_RANK()

CUME_DIST()

NTILE()

RATIO_TO_REPORT()

ROW_NUMBER()

LAG()

FIRST_VALUE()

LAST_VALUE()

NTH_VALUE()

LEAD()

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇mongodb监控工具mongo-monitor安.. 下一篇mysql查看被锁住的表

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目