SQL技巧->分组排序 , 取最新数据的两种方法

写SQL的时候 , 如果要分组取最新的数据 , 一般可以有两种方法

1 drop table if exists #a
 2 
 3     select * into #a from (
 4     select symbol=001,price=10,tdate=20190601
 5     union all
 6     select symbol=001,price=15,tdate=20190801
 7     union all
 8     select symbol=002,price=20,tdate=20190601
 9     union all
10     select symbol=002,price=25,tdate=20190801
11     )a order by tdate
12 
13     select * from #a  -- 查看表中数据
14     -- 常规写法
15     select * from #a x
16     where tdate=(select max(tdate) from #a where x.symbol=symbol)
17 
18     -- 等价写法
19     select symbol,price,tdate from (
20     select symbol,price,tdate,rn=row_number() over(partition by symbol order by tdate desc) from #a 
21     )a where rn=1
22     
23 drop table #a
1 drop table if exists #a 2 3 select * into #a from ( 4 select symbol=001,price=10,tdate=20190601 5 union all 6 select symbol=001,price=15,tdate=20190801 7 union all 8 select symbol=002,price=20,tdate=20190601 9 union all 10 select symbol=002,price=25,tdate=20190801 11 )a order by tdate 12 13 select * from #a -- 查看表中数据 14 -- 常规写法 15 select * from #a x 16 where tdate=(select max(tdate) from #a where x.symbol=symbol) 17 18 -- 等价写法 19 select symbol,price,tdate from ( 20 select symbol,price,tdate,rn=row_number() over(partition by symbol order by tdate desc) from #a 21 )a where rn=1 22 23 drop table #a

结果如下图

前提是 日期字段 tdate不会有重复

1.第一种是用子查询max , 这种方法常用而且简单 但是有局限性 就是只能对一个字段进行排序 , 分组条件即where 后面的条件

  这里是symbol 还可以加上其他的条件比如 x.symbol=symbol and x.exchange=exchange

  这里的条件和分组条件group by以及row_number()的partition by条件实现的功能是一样的

  注意#a的表的别名 x 是写在哪里的 不能写在子查询里面

  如果写在子查询里面那么where x.symbol=symbol就等于没写 相当于取整张表的max(tdate) 没有实现分组作用

  但是刚开始写SQL的时候会难以理解 为啥这样也可以

2.另一种是row_number() 这种方法如果是只用在取最新数据 , 就有点大材小用了 而且不如上一种方法简单 但是他可以在order by tdate 排序之后增加其他的排序规则

比如 order by tdate desc,price desc

但这个例子后面再写其他的排序字段也没用了 因为tdate是唯一的

谢谢!

写SQL的时候 , 如果要分组取最新的数据 , 一般可以有两种方法 1 drop table if exists #a 2 3 select * into #a from ( 4 select symbol=001,price=10,tdate=20190601 5 union all 6 select symbol=001,price=15,tdate=20190801 7 union all 8 select symbol=002,price=20,tdate=20190601 9 union all 10 select symbol=002,price=25,tdate=20190801 11 )a order by tdate 12 13 select * from #a -- 查看表中数据 14 -- 常规写法 15 select * from #a x 16 where tdate=(select max(tdate) from #a where x.symbol=symbol) 17 18 -- 等价写法 19 select symbol,price,tdate from ( 20 select symbol,price,tdate,rn=row_number() over(partition by symbol order by tdate desc) from #a 21 )a where rn=1 22 23 drop table #a 结果如下图 前提是 日期字段 tdate不会有重复 1.第一种是用子查询max , 这种方法常用而且简单 但是有局限性 就是只能对一个字段进行排序 , 分组条件即where 后面的条件   这里是symbol 还可以加上其他的条件比如 x.symbol=symbol and x.exchange=exchange   这里的条件和分组条件group by以及row_number()的partition by条件实现的功能是一样的   注意#a的表的别名 x 是写在哪里的 不能写在子查询里面   如果写在子查询里面那么where x.symbol=symbol就等于没写 相当于取整张表的max(tdate) 没有实现分组作用   但是刚开始写SQL的时候会难以理解 为啥这样也可以 2.另一种是row_number() 这种方法如果是只用在取最新数据 , 就有点大材小用了 而且不如上一种方法简单 但是他可以在order by tdate 排序之后增加其他的排序规则 比如 order by tdate desc,price desc 但这个例子后面再写其他的排序字段也没用了 因为tdate是唯一的 谢谢!
经验分享 程序员 微信小程序 职场和发展