如果我有下表:
ID d_date d_value
----------------------------------------------------------------------
1 1/16/2018 03:41:01 PM 10
2 1/16/2018 03:41:02 PM 20
3 1/16/2018 03:41:03 PM 30
4 1/16/2018 03:44:04 PM 40
5 1/16/2018 03:44:05 PM 50
6 1/16/2018 03:46:06 PM 60
7 1/17/2018 03:41:01 PM 70
8 1/17/2018 03:41:02 PM 80
9 1/17/2018 03:44:03 PM 90
10 1/17/2018 03:45:04 PM 100
需要获取每分钟最后一秒的值。因此,对于上表,结果如下:
ID d_date value
----------------------------------------------------------------------
3 1/16/2018 03:41:03 PM 30
5 1/16/2018 03:44:05 PM 50
6 1/16/2018 03:46:06 PM 60
8 1/17/2018 03:41:02 PM 80
9 1/17/2018 03:44:03 PM 90
10 1/17/2018 03:45:04 PM 100
我不得不使用内连接来实现它:
select dt, mx, d_tb.d_value from (
select to_char(d_date,'YYYY-MM-DD HH24:MI') dt, max(d_date) mx from d_table
group by to_char(d_date,'YYYY-MM-DD HH24:MI')
) d_sub
left outer join d_table d_tb on d_tb.d_date = d_sub.mx
order by dt
表中有数千条记录的问题,有更好的方法吗?
答案 0 :(得分:3)
您可以使用row_number()
:
select d.*
from (select d.*,
row_number() over (partition by to_char(d_date, 'YYYY-MM-DD HH24:MI')
order by d_date desc
) as seqnum
from d_table d
) d
where seqnum = 1;
对于性能,您可以从(to_char(d_date, 'YYYY-MM-DD HH24:MI'), d_date)
上的索引开始。您也可以尝试以下方法(使用相同的索引:
select d.*
from d_table d
where d.d_date = (select max(d2.d_date)
from d_table d2
where to_char(d2.d_date, 'YYYY-MM-DD HH24:MI') = to_char(d.d_date, 'YYYY-MM-DD HH24:MI')
);
在任何一种情况下,性能的关键是基于函数的索引来提取分钟。
正如Boneist所说,trunc(d_date, 'MI')
可能比转换为约会更好。
答案 1 :(得分:2)
另一种方法是使用keep .. dense_rank
with first
or last
,它不需要额外的索引:
select max(id) keep (dense_rank last order by d_date) as id,
max(d_date) as d_date,
max(d_value) keep (dense_rank last order by d_value) as d_value
from d_table
group by trunc(d_date, 'MI');
ID D_DATE D_VALUE
---------- ------------------- ----------
3 2018-01-16 15:41:03 30
5 2018-01-16 15:44:05 50
6 2018-01-16 15:46:06 60
8 2018-01-17 15:41:02 80
9 2018-01-17 15:44:03 90
10 2018-01-17 15:45:04 100
如果有可能在同一秒内有两个值,那么你需要决定如何打破平局 - 即决定使用哪个 - 并适当修改order by
。
trunc(d_date, 'MI')
从日期值中剥离第二个,以便按分钟值分组;并且您需要一个正常的聚合max(d_date)
来获得每个组中最高的实际值。