Sql 从表中选择比较对
我真的不知道该怎么形容它。我有一张桌子:Sql 从表中选择比较对,sql,oracle,select,Sql,Oracle,Select,我真的不知道该怎么形容它。我有一张桌子: ID | Name | Date ------------------------- 1 | Mike | 01.01.2016 1 | Michael | 02.03.2016 2 | Samuel | 23.12.2015 2 | Sam | 05.03.2015 3 | Tony | 02.04.2012 我想选择一对ID和名称,每对中都有最新的日期。这里的结果应该是: ID | Name | Date
ID | Name | Date
-------------------------
1 | Mike | 01.01.2016
1 | Michael | 02.03.2016
2 | Samuel | 23.12.2015
2 | Sam | 05.03.2015
3 | Tony | 02.04.2012
我想选择一对ID和名称,每对中都有最新的日期。这里的结果应该是:
ID | Name | Date
-------------------------
1 | Michael | 02.03.2016
2 | Samuel | 23.12.2015
3 | Tony | 02.04.2012
我如何做到这一点
Oracle Database 11g有一个子选择,返回每个id及其最大日期:
select * from table
where (id, date) in (select id, max(date) from table group by id)
您可以使用
不存在()
:
您可以使用以下方法进行操作:
这只需要一次表扫描(它没有自联接或相关子查询,即(…)中的
或(…)
存在(…)。最有效的方法可能是:
select t.*
from table t
where t.date = (select max(date) from table t2 where t2.id = t.id);
以及表(id,date)
上的索引
此版本应扫描表并在索引中查找正确的值
或者,如果只有三列,可以使用keep
:
select id, max(date) as date,
max(name) keep (dense_rank first order by date desc) as name
from table
group by id;
我发现这个版本在Oracle中运行得非常好。我们如何根据相似的条件匹配名称?它会造成大量数据混乱。。如果两行(或更多行)具有相同的“ID”,我需要选择“日期”列值最大的一行。如果有两行具有相同的
ID
和最大Date
值,您希望的行为是什么?您是只返回其中一行还是同时返回两行?MT0,我只希望返回一行,根据写入这些日期列的过程逻辑,这不应该发生。这将需要两次表扫描-使用分析函数会更有效。如果存在具有相同id
和date
值的行,它还将为id
返回多行。@MTO,是的,那些Oracle分析函数似乎很方便,总有一天要学会使用它们。如果打成平局,多行当然是出于目的!这将需要两次表扫描-使用分析函数将更有效。如果存在具有相同id
和最大date
值的行,它也会为id
返回多行。看起来很有趣,但不幸的是,我无法将其适应我的原始查询:(@ifuwanride您应该能够将表名
替换为(您的查询)
。如果您有问题,那么您可以随时在实际查询中发布新问题,并询问如何对其应用行数()
以筛选最大值。等等,我想是我做的,但我不能在where子句中使用“RN”,它说的是ORA0904“RN”无效identifier@ifuwannaride您需要确保分析函数ROW_NUMBER()的别名为rn
(按id顺序按“日期”描述划分)-请注意结尾处的rn
或为rn
。好的,我成功了,谢谢!很抱歉,我还有一个问题(可能我需要单独打开一个)-如果我想在PartitionBy表达式中使用一对列呢?就像PartitionBy(ID,ID2)一样,这是可能的吗?
select t.*
from table t
where t.date = (select max(date) from table t2 where t2.id = t.id);
select id, max(date) as date,
max(name) keep (dense_rank first order by date desc) as name
from table
group by id;