从简单需求到OLAP的RANK系列函数

同事问了一个非常简单的问题,怎么取出每个partition里面另外一个列的最小值?

create table t1 (int c1, int c2);

 

假如按照c2分区,0-10,10-20,20-30,30-40,40-50

 

insert into t1 values(101, 1);
insert into t1 values(102, 2);
insert into t1 values(111, 11);
insert into t1 values(112, 12);
insert into t1 values(121, 21);
insert into t1 values(122, 22);
insert into t1 values(131, 31);
insert into t1 values(132, 32);
insert into t1 values(133, 32);
insert into t1 values(132, 33);
insert into t1 values(141, 41);
insert into t1 values(142, 42);
insert into t1 values(142, 43);

 

本来这个问题非常简单,但今天死活想不出来了,居然绕着去看RANK系列的OLAP函数,学习了好长时间也发现没办法搞定。

其实只需要按照分区表的范围取整数就可以了

 

select cast(c2/10 as integer), min(c1),max(c1) from t1
group by cast(c2/10 as integer);
 
输出如下:
 1 	2   	3
 - 	--- 	---
 0	101	102
 1	111	112
 2	121	122
 3	131	133
 4	141	142

不过倒是又温习了一下RANK系列函数,简单总结一下:

RANK() 排名函数 ,返回值是不连续的,如果有两个相同的第一名,则第三个值为3

DENSE_RANK() 奥运冠军排名函数,返回值是连续的,可以并列第一,然后第二名,第三名

ROW_NUMBER() 连续值,基本可以看作ORACLE里的ROWNUM

OVER()可以加分区列或者列表达式,这样在输出max(c1)的时候如果分在一个区,所有的值都是一样的

 

SELECT c1,c2,CAST(C2/10 AS INTEGER),MAX(C1) OVER( PARTITION BY CAST(C2/10 AS INTEGER)) FROM T1;

 

得到如下输出:

 C1  	C2 	3 	4
 --- 	-- 	- 	---
 101	 1	0	102
 102	 2	0	102
 111	11	1	112
 112	12	1	112
 121	21	2	122
 122	22	2	122
 131	31	3	133
 132	33	3	133
 133	32	3	133
 132	32	3	133
 141	41	4	142
 142	43	4	142
 142	42	4	142

OVER 内还可以加ORDER BY 用来指定排序的时候用那个column

另外一个非常有用的功能是窗口函数可以在OVER()内指定rows或者range来指定以当前行为范围的一个窗口,在这个窗口内来进行聚集函数的计算。

比如, 我想看看某商品当前日期的价格和此前30天的平均价格:

 
SELECT c1 as price,c2 as days,avg(C1)  OVER(
order by c2 range  30 PRECEDING
) as avg_price
FROM T1;
 

结果如下:

 PRICE 	DAYS 	AVG_PRICE
 ----- 	---- 	---------
   101	   1	      101
   102	   2	      101
   111	  11	      104
   112	  12	      106
   121	  21	      109
   122	  22	      111
   131	  31	      114
   132	  32	      120
   133	  32	      120
   132	  33	      124
   141	  41	      126
   142	  42	      129
   142	  43	      132

在我想来,窗口函数最有用的功能是看当前股票价格和此前一段时间的平均价格。

这就是OLAP之RANK系列函数的简单介绍,有了这些知识之后应该可以很快的写出更多更加有用的SQL。我的感觉是RANK系列函数相当于在处理每一行的数据的同时都可以为某其它列带着group by,非常强大。但千万注意,这里面的任何函数都会导致扫面非常多的数据,所以这类SQL的性能不会太好,千万在online的程序中慎用。

时间: 2024-10-10 19:50:47

从简单需求到OLAP的RANK系列函数的相关文章

posix 线程(一):线程模型、pthread 系列函数 和 简单多线程服务器端程序

posix 线程(一):线程模型.pthread 系列函数 和 简单多线程服务器端程序 一.线程有3种模型,分别是N:1用户线程模型,1:1核心线程模型和N:M混合线程模型,posix thread属于1:1模型. (一).N:1用户线程模型 “线程实现”建立在“进程控制”机制之上,由用户空间的程序库来管理.OS内核完全不知道线程信息.这些线程称为用户空间线程.这些线程都工作在“进 程竞争范围”(process contention scope):各个线程在同一进程竞争“被调度的CPU时间”(但

水题 codeforces 133A - HQ9+ && sting类find系列函数简单总结

题意:给出一个字符串,判断里面有没有'H''Q' '9'三者中的任何一个,如果有的话输出"YES",否则输出"NO"思路:利用string类的find函数进行查找即可code:#include<iostream>#include<string>using namespace std;int main(){ string s; cin >> s; string t("HQ9"); if(s.find_first_

EasyExcel应对简单需求的demo设计

前言 Java解析.生成Excel比较有名的框架有Apache poi.jxl.但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大.easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到几M,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式.在

openssl之EVP系列之10---EVP_Sign系列函数介绍

---依据openssl doc/crypto/EVP_SignInit.pod翻译 (作者:DragonKing, Mail: [email protected] ,公布于:http://openssl.126.com 之openssl专业论坛,版本号:openssl-0.9.7) EVP_Sign系列函数使用的基础结构跟信息摘要算法使用的基础结构是一样的.并且,其前面的两个操作步骤初始化和数据操作(信息摘要)也跟信息摘要算法是一样的,唯一不一样的是最后一步操作.本系列函数做了签名的工作,而信

[OS] 多线程--原子操作 Interlocked系列函数

转自:http://blog.csdn.net/morewindows/article/details/7429155 上一篇<多线程--第一次亲密接触 CreateThread与_beginthreadex本质区别>中讲到一个多线程报数功能.为了描述方便和代码简洁起见,我们可以只输出最后的报数结果来观察程序是否运行出错.这也非常类似于统计一个网站每天有多少用户登录,每个用户登录用一个线程模拟,线程运行时会将一个表示计数的变量递增.程序在最后输出计数的值表示有今天多少个用户登录,如果这个值不等

原子操作 Interlocked系列函数

上一篇<多线程第一次亲密接触 CreateThread与_beginthreadex本质区别>中讲到一个多线程报数功能.为了描述方便和代码简洁起见,我们可以只输出最后的报数结果来观察程序是否运行出错.这也非常类似于统计一个网站每天有多少用户登录,每个用户登录用一个线程模拟,线程运行时会将一个表示计数的变量递增.程序在最后输出计数的值表示有今天多少个用户登录,如果这个值不等于我们启动的线程个数,那显然说明这个程序是有问题的.整个程序代码如下: [cpp] view plain copy #inc

秒杀多线程第三篇 原子操作 Interlocked系列函数

版权声明:本文为博主原创文章,未经博主允许不得转载. 上一篇<多线程第一次亲密接触 CreateThread与_beginthreadex本质区别>中讲到一个多线程报数功能.为了描述方便和代码简洁起见,我们可以只输出最后的报数结果来观察程序是否运行出错.这也非常类似于统计一个网站每天有多少用户登录,每个用户登录用一个线程模拟,线程运行时会将一个表示计数的变量递增.程序在最后输出计数的值表示有今天多少个用户登录,如果这个值不等于我们启动的线程个数,那显然说明这个程序是有问题的.整个程序代码如下:

多线程笔记--原子操作Interlocked系列函数

前面写了一个多线程报数的功能,为了描述方便和代码简洁起见,只输出最后的报数结果来观察程序运行结果.这非常类似一个网站的客户访问统计,每个用户登录用一个线程模拟,线程运行时将一个表示计数的变量递增.程序在最后输出这个计数的值表示今天有多少用户登录.如果这个值不等于我们启动的线程个数,那这个程序就是有问题的. #include <stdio.h> #include <process.h> #include <Windows.h> volatile long g_nLogin

多线程面试秒杀系列4---Interlocked系列函数的简要分析

上一篇中我们出现了脏读的问题,但是却没有给出解决办法这一篇中我们这一篇中主要说明一下interlocked系列函数. 下面列出一些常用的Interlocked系列函数: 1.增减操作 LONG__cdeclInterlockedIncrement(LONG volatile* Addend); LONG__cdeclInterlockedDecrement(LONG volatile* Addend); 返回变量执行增减操作之后的值. LONG__cdec InterlockedExchange