在论坛中出现的比较难的sql问题:4(row_number函数+子查询 分组连续编号问题)

最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了。

所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路。


 

求一查询语句 

 http://bbs.csdn.net/topics/390633004

CREATE #temp (cName CHAR(1),re int)
INSERT #temp
SELECT 'A',1 UNION ALL
SELECT 'A',2 UNION ALL
SELECT 'B',3 UNION ALL
SELECT 'A',4 UNION ALL
SELECT 'A',5

如何查询得到如下的结果:
cName,re,xh
-------------------
'A',1,1
'A',2,1
'B',3,2
'A',4,3
'A',5,3

 

下面是我的解答:

select *,
       dense_rank() over(order by case when exists(select  t2.re from #temp t2 
                                                   where t1.cname = t2.cname 
                                                   and t1.re= t2.re + 1)
                                            then (select  t2.re from #temp t2 
                                                   where t1.cname = t2.cname 
                                                   and t1.re= t2.re + 1)
                                       else t1.re
                                   end
                         ) as xh
from #temp t1
/*
cName re xh
A	  1	 1
A	  2	 1
B	  3	 2
A	  4	 3
A	  5	 3
*/


但是这个解答是有问题的,因为当连续的记录超过3条时,就会有问题,

所以修改了一下,这个是正确的解法:

create table #temp (cName CHAR(1),re int)

insert into #temp
SELECT 'A',1 UNION ALL
SELECT 'A',2 UNION ALL
SELECT 'B',3 UNION ALL
SELECT 'A',4 UNION ALL
SELECT 'A',5 union all
SELECT 'A',6 union all
SELECT 'A',7 union all
SELECT 'D',8 union all
SELECT 'D',9 union all
SELECT 'D',10 union all
select 'B',11 union all
select 'A',12

;with t
as
(
select *,
       row_number() over(partition by cname order by re) as rownum
from #temp 
)

select cname,
       re,
       dense_rank() over(order by case when exists(select min(t2.re) from t t2 
                                                   where t1.cname = t2.cname 
                                                   and t1.re-t1.rownum= t2.re-t2.rownum)
                                            then (select  min(t2.re) from t t2 
                                                   where t1.cname = t2.cname 
                                                   and t1.re-t1.rownum= t2.re-t2.rownum)
                                       else t1.re
                                   end
                         ) as xh
from t t1
/*cname	re	xh
A	1	1
A	2	1
B	3	2
A	4	3
A	5	3
A	6	3
A	7	3
D	8	4
D	9	4
D	10	4
B	11	5
A	12	6
*/


 

转载于:https://www.cnblogs.com/momogua/p/8304556.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值