获取具有最大值的行的最有效方法是什么?
What is the most efficient way to get row with the max value?
假设我们有一家漂亮的酒店。这家酒店的数据库只有一个 table:
room check-in check_out other columns...
1 2020-02-04 2020-02-05 ...
1 2020-02-06 2020-02-09 ...
1 2020-04-20 NULL ...
2 2020-03-29 2020-04-01 ...
2 2020-04-17 2020-04-18 ...
使用 其他列的值 select 每个房间的最后一次签到的最佳和有效方法是什么(否则我只会使用 room, max(check-in)
?
预期结果是
room check_in check_out other columns...
1 2020-04-20 NULL ...
2 2020-04-17 2020-04-18 ...
我想到的第一个想法是加入此 table 及其副本:
WITH last_checkins AS (
SELECT room, max(check_in) AS last_c
FROM rooms
GROUP BY room
)
SELECT *
FROM rooms r
INNER JOIN last_chekins c
ON r.room = c.room
AND r.checkin = c.last_c;
我不喜欢这个想法
- 好像效率有点低。这家酒店有3000万间客房。所以我必须加入两个大 tables
- 我有点害怕参加约会。感觉好像出了什么问题。 Check_in 专栏顺便也有时间。这让它变得更加混乱。
我想知道我的担忧是否相关?
最方便的大概是row_number()
:
select r.*
from (select r.*,
row_number() over (partition by room order by checkin dec) as seqnum
from rooms r
) r
where seqnum = 1;
有了 (room, checkin)
上的索引,这应该也有不错的性能。
有时相关子查询效果更好:
select r.*
from rooms r
where r.checkin = (select max(r2.checkin)
from rooms r2
where r2.room = r.room
);
Oracle 有一个很好的优化器,所以我不确定哪个更适合您的情况。
假设我们有一家漂亮的酒店。这家酒店的数据库只有一个 table:
room check-in check_out other columns...
1 2020-02-04 2020-02-05 ...
1 2020-02-06 2020-02-09 ...
1 2020-04-20 NULL ...
2 2020-03-29 2020-04-01 ...
2 2020-04-17 2020-04-18 ...
使用 其他列的值 select 每个房间的最后一次签到的最佳和有效方法是什么(否则我只会使用 room, max(check-in)
?
预期结果是
room check_in check_out other columns...
1 2020-04-20 NULL ...
2 2020-04-17 2020-04-18 ...
我想到的第一个想法是加入此 table 及其副本:
WITH last_checkins AS (
SELECT room, max(check_in) AS last_c
FROM rooms
GROUP BY room
)
SELECT *
FROM rooms r
INNER JOIN last_chekins c
ON r.room = c.room
AND r.checkin = c.last_c;
我不喜欢这个想法
- 好像效率有点低。这家酒店有3000万间客房。所以我必须加入两个大 tables
- 我有点害怕参加约会。感觉好像出了什么问题。 Check_in 专栏顺便也有时间。这让它变得更加混乱。
我想知道我的担忧是否相关?
最方便的大概是row_number()
:
select r.*
from (select r.*,
row_number() over (partition by room order by checkin dec) as seqnum
from rooms r
) r
where seqnum = 1;
有了 (room, checkin)
上的索引,这应该也有不错的性能。
有时相关子查询效果更好:
select r.*
from rooms r
where r.checkin = (select max(r2.checkin)
from rooms r2
where r2.room = r.room
);
Oracle 有一个很好的优化器,所以我不确定哪个更适合您的情况。