SQL Cookbook 系列 - 范围处理

本文介绍了一系列高级SQL技巧,包括定位连续值范围、查找同一组或分区中行间差值、定义连续值范围的起止点、补充范围内缺失值以及生成连续数值的方法。这些技巧对于处理时间序列数据和数值序列非常有用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 定位连续值的范围
  2. 查找同一组或分区中行之间的差
  3. 定位连续值范围的开始点和结束点
  4. 补充范围内丢失的值
  5. 生成连续数字值

 

1.定位连续值的范围

select v1.project_id,v1.project_start,v1.project_end

from V v1,V v2

where v1.project_end=v2.project_start;

Note:这个会用到,应用场景在连续范围上,可以是数字范围,也可以是日期范围

 

2.查找同一组或分区中行之间的差

db2/mysql/postgresql/sqlserver:

select deptno,ename,hiredate,sal,

coalesce(cast(sal-next_sal as char(10)),'N/A') as diff

from (

select e.deptno,e.ename,e.hiredate,e.sal,

(select min(sal) from emp d

where d.deptno=e.deptno and d.hiredate=

(select min(hiredate) from emp d

where e.deptno=d.deptno and d.hiredate>e.hiredate)) as next_sal

from emp e

) x;

oracle:

select deptno,ename,sal,hiredate,

lpad(nvl(to_char(sal-next_sal),'N/A'),10) as diff

from (

select deptno,ename,sal,hiredate,

lead(sal)over(partition by deptno order by hiredate) next_sal

from emp

);

Note:当数据按照某种条件有序的时候,统计连续两行之间测差

 

3.定义连续值范围的开始点和结束点

db2/mysql/postgresql/sqlserver:

create view V2 as

select a.*,case when (

select b.project_id from V b

where a.project_id=b.project_id

) is null then 0 else 1

end as flag from V a;

 

select project_grp,

min(project_start) as project_start,

max(project_end) as project_end

from (

select a.project_id,a.project_start,a.project_end,

(select sum(b.flag) from V2 b where b.project_id<=a.project_id)

as project_grp

from V2 a

) x group by project_grp;

oracle:

select project_grp,min(project_start),max(project_end)

from (

select project_id,project_start,project_end,

sum(flag)over(order by project_id) project_grp

from (

select project_id,project_start,project_end,

case when lag(project_end)over(order by project_id)=project_start

then 0 else 1 end flag

from V

)

) group by project_grp;

Note:统计某个时间段内记录的情况,多少大小

 

4.补充范围内丢失的值

db2:

select x.yr,coalesce(y.cnt,0) cnt from (

select year(min(hiredate)over())-

mod(year(min(hiredate)over()),10)+

row_number()over()-1 yr

from emp fetch first 10 rows only

) x left join (

select year(hiredate) yr1,count(*) cnt

from emp group by year(hiredate)

) y on (x.yr=y.yr1);

oracle:

select x.yr,coalesce(cnt,0) cnt from (

select extract(year from min(hiredate)over())-

mod(extract(year from min(hiredate)over()),10)+

rownum-1 yr

from emp where rownum<=10

) x left join (

select to_number(to_char(hiredate,'YYYY')) yr,count(*) cnt

from emp group by to_number(to_char(hiredate,'YYYY'))

) y on (x.yr=y.yr);

postgresql/mysql:

select y.yr,coalesce(x.cnt,0) as cnt from (

select min_year-mod(cast(min_year as int),10)+rn as yr from (

select (select min(extract(year from hiredate)) from emp) as min_year,

id-1 as rn

from t10

) a

) y left join (

select extract(year from hiredate) as yr,count(*) as cnt

from emp group by extract(year from hiredate)

) x on (y.yr=x.yr);

sqlserver:

select x.yr,coalesce(y.cnt,0) cnt from (

select top (10)

(year(min(hiredate)over())-

year(min(hiredate)over())%10)+

row_number()over(order by hiredate)-1 yr

from emp

) x left join (

select year(hiredate) yr,count(*) cnt

from emp group by year(hiredate)

) y on (x.yr=y.yr);

Note:这个没有用过,并不是补充数据,是进行查询

 

5.生产连续数字值

db2/sqlserver:

with x(id) as (

select 1 from t1 union all

select id+1 from x where id+1<=10

)

select * from x;

db2:

with x(id) as (

values(1) union all

select id+1 from x where id+1<=10

)

select * from x;

oracle:

select array id from dual

model dimension by (0 idx)

measures(1 array)

rules iterate (10) (

array[iteration_number]=iteration_number+1

);

postgresql:

select id from generate_series(1,10) x(id);

Note: mysql本身有自增的关键字

SQL 是计算机世界的语言,在用关系数据库开发报表时,将数据放入数据库以及从数据库中取出来,都需要SQL 的知识。很多人以一种马马虎虎的态度在使用SQL,根本没有意识到自己掌握着多么强大的武器。本书的目的是打开读者的视野,看看SQL 究竟能干什么,以改变这种状况。, 本书是一本指南,其中包含了一系列SQL 的常用问题以及它们的解决方案,希望能对读者的日常工作有所帮助。本书将相关主题的小节归成章,如果读者遇到不能解决的SQL 新问题,可以先找到最可能适用的章,浏览其中各小节的标题,希望读者能从中找到解决方案,至少可以找到点灵感。, 在这本书中有150 多个小节,这还仅仅是SQL 所能做的事情的一鳞半爪。解决日常编程问题的解决方案的数量仅取决于需要解决的问题的数量,本书没有覆盖所有问题,事实上也不可能覆盖;然而从中可以找到许多共同的问题及其解决方案,这些解决方案中用到许多技巧,读者学到这些技巧就可以将它们扩展并应用到本书不可能覆盖的其他新问题上。, 毫无疑问,本书的目标是让读者看到,SQL 能够做多少一般认为是SQL 问题范围之外的事情。在过去的10 年间,SQL 走过了很长的路,许多过去只能用C 和JAVA等过程化语言解决的典型问题现在都可以直接用SQL 解决了,但是很多开发人员并没有意识到这一事实。本书就是要帮助大家认识到这一点。, 现在,在对我刚才的话产生误解之前我先要申明:我是“如果没坏,就别去修它”这一教义的忠实信徒。例如,假如你有一个特定的业务问题要解决,目前只用SQL检索数据,而其他复杂的业务逻辑由其他语言完成,如果代码没有问题,而且性能也过得去,那么,谢天谢地。我绝对无意建议你扔掉以前的代码重新寻求完全SQL 的解决方案;我只是请你敞开思想,认识到1995 年编程用的SQL 跟2005 年用的不是一回事,今天的SQL 能做的事要多得多。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值