tags:

views:

280

answers:

8
date                 value

18/5/2010, 1 pm        40
18/5/2010, 2 pm        20
18/5/2010, 3 pm        60
18/5/2010, 4 pm        30
18/5/2010, 5 pm        60
18/5/2010, 6 pm        25 

i need to query for the row having max(value)(i.e. 60). So, here we get two rows. From that, I need the row with the lowest time stamp for that day(i.e 18/5/2010, 3 pm -> 60)

A: 

wrap your original query in another SQL statement

SELECT * FROM (SELECT ....) as t ORDER BY date LIMIT 1
Geek Num 88
Oracle doesn't have a LIMIT clause
Gary
A: 

The simplest answer would be

--Setup a test table called "t1"

create table t1
(date datetime,
value int)

-- Load the data. -- Note: date format different than in the question

insert into t1
Select '5/18/2010 13:00',40
union all
Select '5/18/2010 14:00',20
union all
Select '5/18/2010 15:00',60 
union all
Select '5/18/2010 16:00',30 
union all
Select '5/18/2010 17:00',60 
union all
Select '5/18/2010 18:00',25 

-- find the row with the max qty and min date.

select *
from t1
where value = 
    (select max(value)  from t1)
and date = 
    (select min(date) 
    from t1
    where value = (select max(value)  from t1))

I know you can do the "TOP 1" answer, but usually your solution gets just complicated enough that you can't use that for some reason.

JBrooks
Three extra accesses on the same table are just unnecessary in Oracle for this requirement.
Jeffrey Kemp
Extra access? This will have the same execution plan as some of the others on here that look like they do less.... but are less readable. And I understand that Oracle doesn't have a TOP command.
JBrooks
A: 

select top 1 * from table order by value desc , date desc

carlos
Oracle doesn't have a TOP clause
Gary
+3  A: 

Keywords like TOP, LIMIT, ROWNUM, ...etc are database dependent. Please read this article for more information.

http://en.wikipedia.org/wiki/Select_(SQL)#Result_limits

Oracle: ROWNUM could be used.

select * from (select * from table order by value desc, date_column) where rownum = 1;

Sujee
+1 For this question I'd recommend the ROWNUM query. Oracle optimizes these sorts of queries very well (i.e. even though it requires a sort, it doesn't actually sort the entire table - it just keeps the topmost row as it scans the table) - and with an appropriate index it won't even have to do that.
Jeffrey Kemp
A: 

Answer is to add a having clause:

SELECT [columns]
FROM table t1
WHERE value= (select max(value) from table)
AND date = (select MIN(date) from table t2 where t1.value = t2.value)

this should work and gets rid of the neccesity of having an extra sub select in the date clause.

TerrorAustralis
Any non-aggregate in the HAVING clause needs to be part of a GROUP BY clause
Gary
Excelent point. I tested mine on sybase, it lets you get away with that. I modified my answer to suit the required database
TerrorAustralis
um... you still have a sub select - in fact, two of them.
Jeffrey Kemp
Thank you for your feedback, yes there are two, but the standard alternative is to do `AND date = select min(date) from table where value = (select max(value) from table))`. i refference J brooks answer (up 3 from this one) as proof. by refferencing the already aquired value of the previous sub select you save 1 level of nesting
TerrorAustralis
ah, I get what you're saying now. ... of course, all the subselects are unnecessary :)
Jeffrey Kemp
A: 

SELECT TOP (1) * FROM Table ORDER BY CostPrice DESC, Date DESC

Manish kosta
Oracle doesn't have a TOP clause
Gary
A: 

Analytics! This avoids having to access the table twice:

SELECT DISTINCT
       FIRST_VALUE(date_col)  OVER (ORDER BY value_col DESC, date_col ASC),
       FIRST_VALUE(value_col) OVER (ORDER BY value_col DESC, date_col ASC)
FROM   mytable;
Jeffrey Kemp
I would be interested in seeing what kind of performance difference this had, from a purely educational point of view. From Toms asktom.oracle site i had understood there were significant overheads in using FIRST_VALUE. Is it possible that you could direct me to some performance results comparing them?
TerrorAustralis
If you have an index on (value_col, date_col) you'll find that Oracle will do quite well using Sujee's query, since it will use the `COUNT STOPKEY` optimization.
Jeffrey Kemp
It avoids scanning the table twice, but it calculates the first_value column for every row, and then the distinct discards them all but one. Better than most other answers, but aggregating is the way to go here.
Rob van Wijk
Yeah. Sujee beat me to the ROWNUM solution which is better :)
Jeffrey Kemp
A: 
SQL> create table t (mydate,value)
  2  as
  3  select to_date('18/5/2010, 1 pm','dd/mm/yyyy, hh am'), 40 from dual union all
  4  select to_date('18/5/2010, 2 pm','dd/mm/yyyy, hh am'), 20 from dual union all
  5  select to_date('18/5/2010, 3 pm','dd/mm/yyyy, hh am'), 60 from dual union all
  6  select to_date('18/5/2010, 4 pm','dd/mm/yyyy, hh am'), 30 from dual union all
  7  select to_date('18/5/2010, 5 pm','dd/mm/yyyy, hh am'), 60 from dual union all
  8  select to_date('18/5/2010, 6 pm','dd/mm/yyyy, hh am'), 25 from dual
  9  /

Table created.

SQL> select min(mydate) keep (dense_rank last order by value) mydate
  2       , max(value) value
  3    from t
  4  /

MYDATE                   VALUE
------------------- ----------
18-05-2010 15:00:00         60

1 row selected.

Regards, Rob.

Rob van Wijk
Good, but still Oracle will do a full scan - it cannot apply the COUNT STOPKEY optimization, unfortunately :(
Jeffrey Kemp
True. And logical because to know for sure something is the maximal value, you'll have to visit them all, or have them pre-ordered like in an index.
Rob van Wijk