相关子查询 - 在内部查询中分组并重写为 window 函数
Correlated subquery - Group by in inner query and rewrite to window function
我正在查看这个查询:
select ID, date1
from table1 as t1
where date2 = (select max(date2)
from table1 as t2
where t1.ID = t2.ID
group by t2.ID)
首先我不认为 Group by
是必要的。我对吗?其次,将其重写为 window 函数通常更有效吗?
这样看起来对吗?
select ID, date1
from (select ID, date1, row_number() over(partition by ID) as row_num,
max(date2) over(partition by ID) as max_date
from table1)
where row_num = 1;
First of all I don't think the Group by is necessary. Am I right?
你是对的。无论如何,这是一个标量子查询:group by
不会改变结果,因为我们在单个 ID
上进行过滤。在我看来,不使用 group by
会使意图更清晰。
window 函数解决方案不需要 max()
- 过滤就足够了,但是 window 函数需要一个 order by
子句(以及派生的 table 需要一个别名)。所以:
select ID, date1
from (
select ID, date1, row_number() over(partition by ID order by date1 desc) as row_num
from table1
) t1
where row_num = 1;
这与第一个查询完全不一样,因为它不允许连接,而第一个查询允许。如果您想要完全相同的逻辑,请使用 rank()
。
哪个查询执行得更好很大程度上取决于您的数据和结构。相关子查询将利用 (id, date2)
上的索引。这两种解决方案都是解决该问题的规范方法,您可能需要针对您的数据测试这两种解决方案,以了解哪一种更适合您的情况。
我正在查看这个查询:
select ID, date1
from table1 as t1
where date2 = (select max(date2)
from table1 as t2
where t1.ID = t2.ID
group by t2.ID)
首先我不认为 Group by
是必要的。我对吗?其次,将其重写为 window 函数通常更有效吗?
这样看起来对吗?
select ID, date1
from (select ID, date1, row_number() over(partition by ID) as row_num,
max(date2) over(partition by ID) as max_date
from table1)
where row_num = 1;
First of all I don't think the Group by is necessary. Am I right?
你是对的。无论如何,这是一个标量子查询:group by
不会改变结果,因为我们在单个 ID
上进行过滤。在我看来,不使用 group by
会使意图更清晰。
window 函数解决方案不需要 max()
- 过滤就足够了,但是 window 函数需要一个 order by
子句(以及派生的 table 需要一个别名)。所以:
select ID, date1
from (
select ID, date1, row_number() over(partition by ID order by date1 desc) as row_num
from table1
) t1
where row_num = 1;
这与第一个查询完全不一样,因为它不允许连接,而第一个查询允许。如果您想要完全相同的逻辑,请使用 rank()
。
哪个查询执行得更好很大程度上取决于您的数据和结构。相关子查询将利用 (id, date2)
上的索引。这两种解决方案都是解决该问题的规范方法,您可能需要针对您的数据测试这两种解决方案,以了解哪一种更适合您的情况。