表名:t_order_header
字段:out_order_code(订单号),verno(版本号)
PS:由于版本号是VARCHAR2类型,故需要通过to_number()函数转化为数字比较。
方法1:
select c.out_order_code,c.verno
from
t_order_header c,
(
select a.out_order_code,max(to_number(verno))as mver from t_order_header a group by a.out_order_code
) d
where
c.out_order_code = d.out_order_code and c.verno = d.mver;
通过分组的方法找到最大版本号。
方法2:
select out_order_code,verno from
t_order_header a
where 1 >
(
select count(*)
from t_order_header
where out_order_code = a.out_order_code and to_number(a.verno) < to_number(verno)
);
解析:1.首先想象有两张表。看from后面的语句都是t_order_header,说明是两张t_order_header表。
2.sql的执行顺序是从头开始,首先从表t_order_header as a 中,获取第一个,即订单号为AA2020,版本号1。
接着,进入where 语句 1 > (sql语句) 。所以先执行sql语句再进行判断。
3.进入sql语句后,看 where out_order_code = a.out_order_code and to_number(a.verno) < to_number(verno),
意思是a.out_order_code是取到表a的第一个数据,相当于进入where 语句 1 > (sql语句)后 这个值是不变了。
看后面 “and to_number(a.verno) < to_number(verno)” ,a表的第一条数据的版本号是1,显然在右表中只有2,3,4,5版本符合,故
select count(*)
from t_order_header
where out_order_code = AA2020 and 1 < to_number(1、2、3、4、5)
返回的就是4。
-------第一次进入子语句结束,判断 where 语句 1 > 4 。
明显不符合,故开始第二次循环........
一直到表a的版本号为5,在to_number(a.verno) < to_number(verno) 语句中,5 < 1、2、3、4、5恒不成立,故count(*)为0;
where 1>0,成立。把AA2020--5放到结果集里,进行下一个订单号。
-----------------------------
但是,
当表里版本号有为null时,to_number(null)<to_number(-n.....-1,0,1、2、3、4、5...n,null) 是永远不成立的,即count(*)恒为0。
所以在整个语句结束后,该订单号版本号有null时,结果集中该订单号将会出现既有最大版本号又有null的。
--------------------------------
经测试,一万条数据中,方法1比方法2快 2秒。但是又因为版本号为null而出现一个订单号2个版本。综上,建议选择方法1。
参考:
https://www.cnblogs.com/feng924249386/p/5847085.html