我只是想知道,如果以下两个sql语句有任何性能差异或它们基本相同:
从spouse
表(person_id,spouse_id,marriage_date)中选择一个人的最新配偶记录。
select *
from spouse
where (person_id, marriage_date) in ( select person_id, max(marriage_date)
from spouse
group by person_id
)
select *
from spouse s1
where marriage_date = ( select max(marriage_date)
from spouse s2
where s1.person_id = s2.person_id
)
这是报告的常见要求,例如,员工的最新工作,最高教育等等。我想知道您是否更喜欢上述陈述,以及为什么,或者,如果还有其他更好的话方式(在性能/可读性方面)来获得这些最新/最高要求。
答案 0 :(得分:3)
正如之前的回答中已经提到的那样,您可以使用SQL server windowing functions来很好地实现这一目标。
SELECT s1.person_id, s1.marriage_date
FROM spouse s1
JOIN (
SELECT
person_id,
ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY marriage_date DESC) AS Priority
FROM spouse
) s2
ON s2.person_id = s1.person_id AND s2.Priority = 1
在联接查询中,我们按person_id
对数据进行分区,然后应用排名函数(ROW_NUMBER()
),按marriage_date
的降序为每行分配一个数字。排名是针对每个person_id
独立完成的,因此加入条件s2.Priority = 1
表示我们只获得每个人的最大marriage_date
记录。
您可能会发现以下内容:
答案 1 :(得分:1)
您可以使用分析函数来执行此操作:
SELECT *
FROM (SELECT ROW_NUMBER() OVER (PARTITION BY person_id
ORDER BY marriage_date DESC) AS r,
t.*
FROM spouse t) x
WHERE x.r = 1
您可以通过查看执行计划来比较所有查询的效率。
答案 2 :(得分:0)
您的示例在语法上是相同的。根据经验,当子查询是最严格的(即从结果集中删除大量记录)时使用IN,并在外部查询最具限制时使用相关子查询(即子查询的记录多于总数结果集)。
根据表统计信息和估计成本,Oracle查询优化器可能会将IN子句重写为相关子查询,反之亦然。查看适合您情况的解释计划,并以最低的成本选择计划。