本来公司说是要做BI的,后来被改成了一个报表系统,失去了体验BI的机会,有些不爽。
报表系统是由顾问公司做,顾问公司说要看我们的SQL水平,给出了一份试题,其中有一题是这样的:
t_hykbgjl 记录了会员卡每次的发生额(nFse) 、余额(nYe)及卡号(sKH),对于同一会员卡,上一条记录的余额加上本次发生额应等于本次的余额。否则帐将不平。记录号为sJlbh,请写出列出所有会员卡不平帐记录的Sql语句。 |
从题目上分析,需要把上一行的余额拿下来进能计算,如果采用传统写法,可能需要很多的嵌套,一个表要查询很多次,由此想到了分析函数,在请教一神货之后,得知
lag 函数可以把上一行某个字段的数据取下来,最终结果如下:
1 CREATE TABLE T_HYKBGJL
2 ( SKH VARCHAR2(20 BYTE),
3 NFSE NUMBER(12,4),
4 NYE NUMBER(12,4),
5 SJLBH NUMBER
6 );
insert into t_hykbgjl(skh,nfse,nye,sjlbh) values(‘I0000000008‘,12,12,1);
insert into t_hykbgjl(skh,nfse,nye,sjlbh) values(‘I0000000011‘,12,12,2);
insert into t_hykbgjl(skh,nfse,nye,sjlbh) values(‘G0000000070‘,10,10,3);
insert into t_hykbgjl(skh,nfse,nye,sjlbh) values(‘G0000000070‘,-2,8,4);
insert into t_hykbgjl(skh,nfse,nye,sjlbh) values(‘G0000000070‘,6,19,5);
insert into t_hykbgjl(skh,nfse,nye,sjlbh) values(‘G0000000070‘,-6,13,6);
insert into t_hykbgjl(skh,nfse,nye,sjlbh) values(‘I0000000008‘,-2,10,7);
insert into t_hykbgjl(skh,nfse,nye,sjlbh) values(‘I0000000008‘,3,13,8);
insert into t_hykbgjl(skh,nfse,nye,sjlbh) values(‘I0000000011‘,-2,10,9);
insert into t_hykbgjl(skh,nfse,nye,sjlbh) values(‘I0000000008‘,6,19,10);
insert into t_hykbgjl(skh,nfse,nye,sjlbh) values(‘I0000000011‘,3,13,11);
insert into t_hykbgjl(skh,nfse,nye,sjlbh) values(‘I0000000008‘,-9,10,12);
insert into t_hykbgjl(skh,nfse,nye,sjlbh) values(‘I0000000011‘,6,19,13);
1 select sjlbh, skh, nfse, nye, prev_ye, prev_ye + nfse
2 from (select sjlbh,
3 skh,
4 nfse,
5 nye,
6 lag(nye, 1, 0) over(partition by skh order by sjlbh) prev_ye
7 from t_hykbgjl)
8 where nye <> (prev_ye + nfse);
最终得出有差异的那行数据。
测试就这样提交了。由于顾问公司那边用的是SQL
Server数据库,与我所用的Oracle还是有区别,所以顾问公司那边最终给出的标准答案令我非常失望。
也是这道题目,让我对分析函数产生了前所未有的兴趣。
分析函数之初体验(一)——一道题目产生的兴趣,码迷,mamicode.com
时间: 2024-10-05 16:30:59