2

What I want: I'm having problems with a greatest-n-per-group problem. My group is a set of TCP Addresses and the n is the date at which the table row was inserted into the database.

The problem: I'm currently getting all rows with tcp Addresses which match my where clause, rather then one with the largest date per tcp address.

I'm trying to follow this example and failing: SQL Select only rows with Max Value on a Column.

Here's what my table looks like.

CREATE TABLE IF NOT EXISTS `xactions` (
  `id` int(15) NOT NULL AUTO_INCREMENT,
  `tcpAddress` varchar(40) NOT NULL,
   //a whole lot of other stuff in batween
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=150 ;

Example rows are

ID | tcpAddress     | ...  | date
1  |  192.168.1.161 | ...  | 2012-09-12 14:19:39
2  |  192.168.1.162 | ...  | 2012-09-12 14:19:40
3  |  192.168.1.162 | ...  | 2012-09-12 14:19:41
4  |  192.168.1.162 | ...  | 2012-09-12 14:19:42

SQL statement I'm trying to use

select yt.id, yt.tcpAddress, yt.analog, yt.discrete, yt.counter, yt.date
from xactions yt
inner join(
    select id, tcpAddress, analog, discrete, counter, max(date) date
    from xactions
    WHERE tcpAddress='192.168.1.161' OR tcpAddress='192.168.1.162'
    group by date
) ss on yt.id = ss.id and yt.date= ss.date
Community
  • 1
  • 1
AlexLordThorsen
  • 8,057
  • 5
  • 48
  • 103

2 Answers2

1

You need to group by the tcpAddress, not by the date.

And join by the tcpAddress, not the id.

select yt.id, yt.tcpAddress, yt.analog, yt.discrete, yt.counter, yt.date 
from xactions yt 
inner join ( 
  select tcpAddress, max(date) date 
  from xactions 
  where tcpAddress in ('192.168.1.161', '192.168.1.162')
  group by tcpAddress
 ) ss using (tcpAddress, date);

Also, you don't need to select any extra columns in the derived table -- only the tcpAddress and the max(date).

Bill Karwin
  • 538,548
  • 86
  • 673
  • 828
1

Also you can use option with EXISTS(). In EXISTS() find MAX(date) for each group of tcpAddress and compare them

SELECT id, tcpAddress, analog, discrete, counter, date
FROM xactions x1    
WHERE EXISTS (
              SELECT 1
              FROM xactions x2
              WHERE x1.tcpAddress = x2.tcpAddress
              HAVING MAX(x2.date) = x1.date
              ) AND (tcpAddress='192.168.1.161' OR tcpAddress='192.168.1.162')
Aleksandr Fedorenko
  • 16,594
  • 6
  • 37
  • 44