Oracle中最近的日期

时间:2014-07-31 20:30:26

标签: sql oracle11g

我正在尝试获取Oracle中给定日期的最接近日期。我一直在工作How to get the closest dates in Oracle sql,但该问题中的示例使用两个不同的表。我不是PL SQL大师,而是我努力让这个工作起来。我有一个包含ID字段和Date字段的表。我需要最接近查询日期的ID。

select *
  from ( select SEQ_ID, ENTERED_DATE, rank() over ( partition by ENTERED_DATE order by difference asc ) as rnk
         from ( select SEQ_ID, ENTERED_DATE, abs(ENTERED_DATE - 2/9/1999) from DOWNTIME_DETAILS)) as difference             
 where rnk = 1

这给了我一个错误:" SQL命令未正确结束"

如何修复查询?我究竟做错了什么?

1 个答案:

答案 0 :(得分:2)

as difference正在分配别名。您不能将as用于表别名,仅用于列别名(因此as rnk可以)。 只需删除第二个as当您在外部查询中引用difference时,看起来您认为它是一个列别名并且只是在错误中地点:

select *
from (
  select SEQ_ID, ENTERED_DATE,
    rank() over ( order by difference ) as rnk
  from (
    select SEQ_ID, ENTERED_DATE,
      abs(ENTERED_DATE - to_date('2/9/1999', 'MM/DD/YYYY')) as difference
    from DOWNTIME_DETAILS
  )
)
where rnk = 1

您还有一个没有任何引号的日期,因此在这种情况下会被解释为数字,并且不会产生您想要的效果。你应该总是使用显式转换;我已经猜到了你的日期格式。并且您不应该按原始entered_date进行分区,因为这将使所有内容排名为1.如果您有两个具有相同差异的记录,它们仍将排名为1,因此您将看到两者。您可以通过修改order by来添加断开关系的方法,例如

    rank() over ( order by difference , entered_date, seq_id ) as rnk

...但您需要指定标准,以便对您的数据和情况有所帮助。

你也可以这样做:

select max(SEQ_ID) keep (dense_rank first
    order by abs(ENTERED_DATE - to_date('2/9/1999', 'MM/DD/YYYY')))
    as seq_id,
  max(ENTERED_DATE) keep (dense_rank first
    order by abs(ENTERED_DATE - to_date('2/9/1999', 'MM/DD/YYYY')))
    as entered_date
from DOWNTIME_DETAILS;

...但是你必须提供两次日期。