在论坛中出现的比较难的sql问题:2(row_number函数+子查询)

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

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

 


1、数据统计的问题。

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

有2个字段,Profit, profitSum。默认profitSum的值为0。如下图


现在要做下统计,规则第一条profitSum的值就为Profit
第二条profitSum的值为第一条的profitSum+第二条的Profit
第三条profitSum的值为第二条的profitSum+第三条的Profit,

结果集如下图

 

我的解法:

--drop table tb


create table tb
(
Profit decimal(10,2),
profitSum decimal(10,2)
)


insert into tb
select 20000.0,0.00 union all
select 5.00,0.00 union all
select 0.00,0.00 union all
select 0.00,0.00 union all
select -383.40,0.00 union all
select 379.80,0.00 union all
select 3.50,0.00


;with t 
as
(
select *,
       row_number() over(order by @@servername) as rownum
from tb
)

select profit,
       (select sum(profit) 
        from t t2 
        where t2.rownum <=  t1.rownum)  as profitSum
from t t1

/*
profit	    profitSum
20000.00	20000.00
5.00	    20005.00
0.00	    20005.00
0.00	    20005.00
-383.40	    19621.60
379.80	    20001.40
3.50	    20004.90
*/


 

2、如何去掉字段内的重复。
http://bbs.csdn.net/topics/390620555?page=1#post-395843873
不是去整行,行都是唯一的,如,现有下表:
 零件号      名称   装入上级   装入数量  总数量
TI4.005      A     AA          1       1
TI4.005     A     BB          1       1
TI4.005     A     CC          2       2
TI4.005                               4

希望得到的结果:
TI4.005      A     AA          1       1
                         BB           1       1
                        CC           2       2
                                                  4
如何用sql实现?
我的解法,不过这个解法需要数据是按照一定的顺序输入的,因为语句中只查找上一行的数据,和上一行进行比较,如果没有顺序,可能会有问题:
;with t(零件号,      名称,   装入上级 ,  装入数量,  总数量)
as
(
select 'TI4.005',    'A',     'AA',          1,       1 union all
select 'TI4.005',    'A',     'BB',          1,       1 union all
select 'TI4.005',    'A',     'CC',          2,       2 union all
select 'TI4.005',    null,      null,        null,    4 
),

tt
as
(
select *,
       row_number() over(partition by 零件号 order by 零件号) as rownum
from t
)


select case when 零件号 = (select top 1 零件号 from tt t2 
                           where t1.零件号 = t2.零件号
                                 and t2.rownum < t1.rownum 
                           order by t2.rownum desc)
                  then null
            else 零件号
       end as 零件号,
       
       case when 名称 = (select top 1 名称 from tt t2 
                           where t1.零件号 = t2.零件号
                                 and t2.rownum < t1.rownum 
                           order by t2.rownum desc)
                  then null
            else 名称
       end as 名称,
       
       case when 装入上级 = (select top 1 名称 from tt t2 
                           where t1.零件号 = t2.零件号
                                 and t2.rownum < t1.rownum 
                           order by t2.rownum desc)
                  then null
            else 装入上级
       end as 装入上级,
       
       装入数量,
       总数量 
from tt t1
/*
零件号	名称	    装入上级	装入数量	总数量
TI4.005	A	    AA	        1	        1
NULL	NULL	    BB	        1	        1
NULL	NULL	    CC	        2	        2
NULL	NULL	    NULL	NULL	        4
*/

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值