Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check multiple rows for value, return only row with MAX/MIN

I'm trying to write a query that will compare the value of N amount of rows and return only the row with the max value. For example, if I wanted to only return a table with non-duplicate rows, but only the row with the newest date -

key  | name  | value |   date
 1   | frank |  100  | 1/1/2013
 2   | peter |  200  | 2/1/2013
 3   | jonny |  300  | 3/1/2013
 4   | jonny |  300  | 4/1/2013

And the query:

SELECT key, name, value, MAX(date)
FROM myTable
WHERE key IN (1,2,3,4)

I'd be expecting this to return

key  | name  | value |   date
 1   | frank |  100  | 1/1/2013
 2   | peter |  200  | 2/1/2013
 4   | jonny |  300  | 4/1/2013

I am unsure how to use GROUP BY, I think I'm missing something fundamental with my attempts at it.

like image 849
Jamie S Avatar asked Oct 04 '13 02:10

Jamie S


People also ask

Does SQL Max return multiple rows?

Answer. Typically, when you have more than one row that contains the minimum or maximum value in a column, the topmost row containing that value will be returned in the result.

How do I SELECT both min and max in SQL?

To ask SQL Server about the minimum and maximum values in a column, we use the following syntax: SELECT MIN(column_name) FROM table_name; SELECT MAX(column_name) FROM table_name; When we use this syntax, SQL Server returns a single value. Thus, we can consider the MIN() and MAX() functions Scalar-Valued Functions.


2 Answers

Well if you only want the newest row you could use the following:

SELECT TOP 1 key, name, value, date
FROM myTable
ORDER BY date desc

This should return the one row with the newest date in that table.

If you wanted the newest date for each name you could use group by:

SELECT name, max(date)
FROM myTable
WHERE key in(1,2,3,4)
GROUP BY name

Max is an aggregate function. Anytime you use an aggregate function any columns that are not being aggregated have to be specified in the group by clause.

So based on your expected results you probably want this:

;with namesWithMaxDate as(
 select
   name
  ,max(date) as date
 from
   myTable 
 group by
   name 
 )
 select 
   myTable.[key]
  ,myTable.name
  ,myTable.value
  ,myTable.date
 from myTable
 inner join
 namesWithMaxDate 
 on 
   myTable.name = namesWithMaxDate.name and 
   myTable.date = namesWithMaxDate.date

This is slightly more complex because you have columns that you want returned that are not included in the grouping. Hence two statements to arrive at the final result set.

Final option: good old fashioned sub-query.

 select 
   myTable.[key]
  ,myTable.name
  ,myTable.value
  ,myTable.date
 from myTable
  inner join
 (   select
       name
      ,max(date) as date
     from
       myTable 
     group by
       name ) as namesWithMaxDate
 on 
   myTable.name = namesWithMaxDate.name and 
   myTable.date = namesWithMaxDate.date

More here about aggregate functions. More here about group by.

like image 51
Michael Avatar answered Oct 14 '22 19:10

Michael


Try This one:

SELECT a.key, a.name, a.value, a.date
FROM myTable a 
WHERE a.key IN (1,2,3,4)
and 
a.DATE = (select MAX(date) from myTable b where a.key = b.key)
like image 44
The Hill Boy Avatar answered Oct 14 '22 17:10

The Hill Boy