• 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

    结果如下图

    前提是 日期字段 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是唯一的

    谢谢!

  • 相关阅读:
    使用iOS网络请求
    Invalid RNPermission 'ios.permission.xxx'. should be one of: ( )
    React Native 报错 Error: spawn EACCES 权限
    React Native 适配Android物理返回键,实现连续两次点击退出
    图解:平衡二叉树,AVL树
    NOIP 骗分技巧
    P1004 方格取数
    5. 最长回文子串
    全链路压测自动化实践
    深度学习在美团配送ETA预估中的探索与实践
  • 原文地址:https://www.cnblogs.com/chendongblog/p/10839534.html
Copyright © 2020-2023  润新知