- 计算平均值
- 求某列中的最小值最大值
- 对某列的值求和
- 求一个表的行数
- 求某列值的个数
- 生成累积和
- 生成累乘积
- 计算累积差
- 计算模式
- 计算中间值
- 求总和的百分比
- 对可控列做聚集
- 计算不包含最大值和最小值的均值
- 把字母数字串转换为数值
- 更改累积和中的值
1.计算平均值
select deptno,avg(sal) as avg_sal from emp group by deptno;
2.求某列中的最小值最大值
select deptno,min(sal) as min_sal,max(sal) as max_sal from emp group by deptno;
3.对某列的值求和
select sum(sal) from emp group by deptno;
4.求一个表的行数
select count(*) fom emp group by deptno;
5.求某列值的个数,非null值的个数
select count(comm) from emp group by deptno;
6.生成累计和
db2,oracle : select ename,sal,sum(sal) over (order by sal,empno) as running_total from emp order by sal;
mysql,postgreSQL,sqlserver : select e.ename,e.sal,(select sum(d.sal) from emp d where d.empno<=e.deptno) as running_total from emp e order by running_total;
7.生成累乘积
db2,oracle : select empno,ename,sal,exp(sum(ln(sal)) over (order by sal,empno)) as running_prod from emp where deptno=10;
mysql,postgresql,sqlserver : select e.empno,e.ename,e.sal,
(select exp(sum(ln(d.sal))) from emp d where d.empno<=e.empno and e.deptno=d.deptno) as running_prod
from emp e where e.deptno=10
Note:sqlserver 要使用log代替ln
8.计算累计差
db2,oracle : select ename,sal,sum(case when rn=1 then sal else -sal end) over (order by sal,empno) as running_diff from
(select empno,ename,sal,row_number() over (order by sal,empno) as rn from emp where deptno=10 ) x;
mysql,postgresql,sqlserver : select a.empno,a.ename,a.sal,
(select case when a.empno=min(b.empno) then sum(b.sal) else sum(-b.sal) end from emp b where b.empno<=a.empno and b.deptno=a.deptno ) as rnk
from emp a where a.deptno=10;
9.计算模式
模式:对给定数据集出现最频繁的元素
db2,sqlserver,oracle : select sal from ( select sal,dense_rank() over (order by cnt desc) as rnk
from (select sal,count(*) as cnt from emp where deptno=20
group by sal) x ) y where rnk=1;
mysql,postgreSQL: select sal from emp where deptno=20 group by sal
having count(*)>=
all(select count(*) from emp where deptno=20 group by sal);
10.计算中间值
db2 : select avg(sal) from (select sal,count(*) over() total,cast(count(*) over() as decimal)/2 mid,
ceil(cast(count(*) over as decimal)/2) next,
row_number() over (order by sal) rn from emp where dept=20)
x where (mod(total,2)=0 and rn in(mid,mid+1)) or
(mod(total,2)=1 and rn=next);
mysql,postgresql : select avg(sal) from (select e.sal from emp e,emp d
where e.deptno=d.deptno and e.deptno=20 group by e.sal
having sum(case when e.sal=d.sal then 1 else 0 end)
>=abs(sum(sign(e.sal-d.sal))));
oracle 10g : select median(sal) from emp where deptno=20;
sqlserver: select avg(sal) from (select sal,count(*) over() total,cast(count(*) over() as decimal)/2 mid,
ceil(cast(count(*) over as decimal)/2) next,
row_number() over (order by sal) rn from emp where dept=20)
x where (total%2=0 and rn in(mid,mid+1)) or
(total%2=1 and rn=next);
11.求总和的百分比
mysql,postgreSQL: select (sum(case when deptno=10 then sal end)/sum(sal))* 100 as pct
from emp;
db2,oracle,sqlserver: select distinct (d10/total)*100 as pct from
(select deptno,sum(sal) over() total,sum(sal) over (partition by deptno) d10 from emp ) x where deptno=10;
12.对可空列做聚集
select avg(coalesce(comm,0)) as avg_comm from emp where deptno=30;
13.计算不包含最大值和最小值的均值
mysql,postgresql : select avg(sal) from emp where sal not in
(select min(sal) from emp,select max(sal) from emp);
db2,oracle,sqlserver : select avg(sal) from (
select sal,min(sal) over() min_sal,max(sal) over max_sal from emp
) x where sal not in (min_sal,max_sal);
14.将字母数字转换为数值
db2 : select cast(replace(translate(ename,repeat('#',26),'qwertyuioplkjhgfdsazxcvbnm'),'#','') as integer) as num from emp;
oracle,postgresql : select cast(replace(translate(ename,'qwertyuioplkjhgfdsazxcvbnm',rpad('#',26,'#')),'#','') as integer) as num from emp;
mysql和sqlserver暂时不支持translate函数
15.更改累积和中的值
虽然表中数据均是正值,但是在某种类型下是以负值累计的
db2,oracle : select case when trx='PY' then 'payment' else 'purchase' end trx_type,amt,
sum(case when trx='PY' then -amt else amt end) over (order by id,amt) as bal
from py_table;
mysql,postgresql,sqlserver : select case when v1.trx='PY' then 'payment' else 'purchase' end as trx_type,v1.amt,(select sum(case when v2.trx='PY' then -v2.amt else v2.amt end) from v v2 where v2.id<=v1.id) as bal from v v1;
Note:使用数字统计的时候,要进行合理的检查,特别是在多条件以及表联接查询的时候