利用rownumber ,关键字partition进行小范围分页
方法一:
--所有供应商对该产品最近的一次报价
with oa as(select a.SupplierId ,UnitPrice,ProductBaseId, detail.LastModified,detail.Id from Latent_Export.dbo.bjQuotationForm a inner join bjQuotationFormDetail detail on detail.QuotationFormId=a.Idwhere ProductBaseId='4CEA04EE-8B70-477D-AC26-0098D13DC2B2' and UnitPrice>0order by SupplierId,LastModified desc),ob as(select a.SupplierId,MAX(a.LastModified) as LastModified from oa a group by a.SupplierId)select *from ob inner join bjQuotationForm b on ob.SupplierId=b.SupplierId inner join bjQuotationFormDetail con ob.LastModified=c.LastModified and b.Id=c.QuotationFormId--方法二:(改进)
SELECT SupplierId,LastModified,ProductBaseId,UnitPrice FROM (select ROW_NUMBER() OVER (partition by form.SupplierId order by detail.LastModified desc) as row, form.SupplierId ,UnitPrice,ProductBaseId, detail.LastModified from Latent_Export.dbo.bjQuotationForm form inner join bjQuotationFormDetail detail on detail.QuotationFormId=form.Idwhere ProductBaseId='4CEA04EE-8B70-477D-AC26-0098D13DC2B2' and UnitPrice>0 ) S WHERE S.row=1--某个供应商对该产品的所有报价select top 50 * from bjQuotationForm form inner join bjQuotationFormDetail detailon form.Id =detail.QuotationFormIdwhere ProductBaseId='4CEA04EE-8B70-477D-AC26-0098D13DC2B2' and SupplierId='E2F18AB9-0468-4CA9-BB4C-500D59BEC958'order by detail.LastModified desc参考:http://www.cnblogs.com/lanzi/archive/2010/10/26/1861338.html
OVER(PARTITION BY)函数介绍
开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化,举例如下:
1:over后的写法: over(order by salary) 按照salary排序进行累计,order by是个默认的开窗函数 over(partition by deptno)按照部门分区
2:开窗的窗口范围:over(order by salary range between 5 preceding and 5 following):窗口范围为当前行数据幅度减5加5后的范围内的。
举例:
--sum(s)over(order by s range between 2 preceding and 2 following) 表示加2或2的范围内的求和
select name,class,s, sum(s)over(order by s range between 2 preceding and 2 following) mm from t2 adf 3 45 45 --45加2减2即43到47,但是s在这个范围内只有45 asdf 3 55 55 cfe 2 74 74 3dd 3 78 158 --78在76到80范围内有78,80,求和得158 fda 1 80 158 gds 2 92 92 ffd 1 95 190 dss 1 95 190 ddd 3 99 198gf 3 99 198
举例:
3、与over函数结合的几个函数介绍
下面以班级成绩表t2来说明其应用
t2表信息如下:
cfe 2 74dss 1 95ffd 1 95fda 1 80gds 2 92gf 3 99ddd 3 99adf 3 45asdf 3 553dd 3 78select * from ( select name,class,s,rank()over(partition by class order by s desc) mm from t2 ) where mm=1;得到的结果是:dss 1 95 1ffd 1 95 1gds 2 92 1gf 3 99 1ddd 3 99 1 注意: 1.在求第一名成绩的时候,不能用row_number(),因为如果同班有两个并列第一,row_number()只返回一个结果;select * from ( select name,class,s,row_number()over(partition by class order by s desc) mm from t2 ) where mm=1;1 95 1 --95有两名但是只显示一个2 92 13 99 1 --99有两名但也只显示一个 2.rank()和dense_rank()可以将所有的都查找出来:如上可以看到采用rank可以将并列第一名的都查找出来; rank()和dense_rank()区别: --rank()是跳跃排序,有两个第二名时接下来就是第四名;select name,class,s,rank()over(partition by class order by s desc) mm from t2dss 1 95 1ffd 1 95 1fda 1 80 3 --直接就跳到了第三gds 2 92 1cfe 2 74 2gf 3 99 1ddd 3 99 13dd 3 78 3asdf 3 55 4adf 3 45 5 --dense_rank()l是连续排序,有两个第二名时仍然跟着第三名select name,class,s,dense_rank()over(partition by class order by s desc) mm from t2dss 1 95 1ffd 1 95 1fda 1 80 2 --连续排序(仍为2)gds 2 92 1cfe 2 74 2gf 3 99 1ddd 3 99 13dd 3 78 2asdf 3 55 3adf 3 45 4--sum()over()的使用select name,class,s, sum(s)over(partition by class order by s desc) mm from t2 --根据班级进行分数求和dss 1 95 190 --由于两个95都是第一名,所以累加时是两个第一名的相加ffd 1 95 190 fda 1 80 270 --第一名加上第二名的gds 2 92 92cfe 2 74 166gf 3 99 198ddd 3 99 1983dd 3 78 276asdf 3 55 331adf 3 45 376
first_value() over()和last_value() over()的使用
--找出这三条电路每条电路的第一条记录类型和最后一条记录类型
注:rows BETWEEN unbounded preceding AND unbounded following 的使用
--取last_value时不使用rows BETWEEN unbounded preceding AND unbounded following的结果
如下图可以看到,如果不使用
数据如下:
取出该电路的第一条记录,加上ignore nulls后,如果第一条是判断的那个字段是空的,则默认取下一条,结果如下所示:
lead(expresstion,<offset>,<default>)
with a as (select 1 id,'a' name from dual union select 2 id,'b' name from dual union select 3 id,'c' name from dual union select 4 id,'d' name from dual union select 5 id,'e' name from dual) select id,name,lead(id,1,'')over(order by name) from a;--ratio_to_report(a)函数用法 Ratio_to_report() 括号中就是分子,over() 括号中就是分母with a as (select 1 a from dual union allselect 1 a from dual union allselect 1 a from dual union allselect 2 a from dual union all select 3 a from dual union allselect 4 a from dual union allselect 4 a from dual union allselect 5 a from dual )select a, ratio_to_report(a)over(partition by a) b from a order by a; with a as (select 1 a from dual union allselect 1 a from dual union allselect 1 a from dual union allselect 2 a from dual union all select 3 a from dual union allselect 4 a from dual union allselect 4 a from dual union allselect 5 a from dual )select a, ratio_to_report(a)over() b from a --分母缺省就是整个占比order by a; with a as (select 1 a from dual union allselect 1 a from dual union allselect 1 a from dual union allselect 2 a from dual union all select 3 a from dual union allselect 4 a from dual union allselect 4 a from dual union allselect 5 a from dual )select a, ratio_to_report(a)over() b from agroup by a order by a;--分组后的占比