仅在ORACLE SQL中选择MIN值

时间:2012-02-29 22:28:23

标签: sql oracle min rank

我想从我的数据集中选择最早的日期和时间,并仅显示符合要求的那些行。并显示3列。

我得到它按日期和时间以正确的顺序显示数据。我怎样才能让它显示具有最小值的数据?我尝试使用first,limit和top x,但它们不起作用,并且不正是我需要的,因为答案可能有多个值。

这是我的示例sql:

Select report, date, time
  From events
 order by date, time

3 个答案:

答案 0 :(得分:4)

试试这个:

 SELECT report, date, time
 FROM (SELECT report, date, time,
         ROW_NUMBER() OVER(PARTITION BY report ORDER BY date ASC, time ASC) AS RowNum
       From events
      ) AS CTE 
 WHERE CTE.RowNum = 1 

答案 1 :(得分:1)

猜测数据类型并不清楚,但这样的事情可能有用(例如使用CTE生成虚拟数据):

with events as (
select 'report1' as report, '01/01/2012' as date_field, '0800' as time_field
    from dual
union all select 'report1', '01/01/2012', '0900' from dual
union all select 'report1', '01/02/2012', '0930' from dual
union all select 'report2', '01/01/2012', '0900' from dual
union all select 'report2', '01/01/2012', '0900' from dual
union all select 'report2', '01/01/2012', '1000' from dual
)
select report, date_field, time_field
from (
    select report, date_field, time_field,
        row_number() over (partition by report
            order by to_date(date_field, 'MM/DD/YYYY'), time_field) as rn
    from events
)
where rn = 1
order by report;

REPORT  DATE_FIELD TIME
------- ---------- ----
report1 01/01/2012 0800
report2 01/01/2012 0900

您可能有不同的日期格式掩码;当你提到“军事时间”时,我假设美国格式。

根据您想要处理关系的方式,您需要rankdense_rank而不是row_number。有关详细信息,请参阅analytic functions的文档。正如Justin所指出的那样,你可能想要rank,它使用相同的数据给出:

REPORT  DATE_FIELD TIME
------- ---------- ----
report1 01/01/2012 0800
report2 01/01/2012 0900
report2 01/01/2012 0900

内部选择会添加一个额外的rn列,为每个结果分配排名; report的每个值至少会有一行被分配1(如果使用rank,则只有一行),可能包含2,{{1}的行3的那个人将拥有该报告的最早日期/时间。外部查询然后通过1子句过滤到显示排名1的那些,因此仅为每个where rn = 1提供具有最早日期/时间的数据 - 其余的被丢弃。

答案 2 :(得分:1)

假设每一行都有一个有效格式化的日期和时间组件,这样的事情应该有效。

SELECT report,
       dt,
       time
  FROM (SELECT report,
               dt,
               time,
               rank() over (partition by report
                                order by to_date( dt || ' ' || time, 'MM/DD/YYYY HH24MI' ) asc) rnk
          FROM events)
 WHERE rnk = 1

但是,从数据模型的角度来看,您应始终将日期存储在DATE列中,而不是尝试将其存储在VARCHAR2列中。由于您需要日期比较和排序语义,因此您必须将数据转换为DATE,这在运行时很昂贵。并且很可能有人最终会在列中以不同的格式存储数据或存储无效的字符串(即'02 / 29/2011'的一天),这将导致您的查询开始生成错误。