views:

68

answers:

2

I've got a table that helps me keep track of the delay times between my slaves and the master. My question is how can I craft a select statement that:
1. gives me the latest delay values, without repeating (or skipping) ip addresses
2. doesn't need to be updated if I add additional servers, or as servers become unresponsive

The goal of this query is to show me what servers are available to do work, and give me a rough estimate as to how hard they are working. Servers that are not operational, shouldn't appear in the results. I'm running a script to evaluate the delay times as CLI every minute, so if I could limit the possible records returned to the last minute and a half, that should be good enough to tell me which servers were up the last time they were queried.

Table looks like this (columns renamed to protect the innocent):

id INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,  
ip VARCHAR( 20 ) NOT NULL ,  
sent TIMESTAMP NOT NULL ,  
delay DECIMAL ( 7,4 ) NOT NULL ,  
status VARCHAR( 100 ) NOT NULL ,  
execution_time` DECIMAL ( 7,4 )NOT NULL ,  
deleted` TINYINT NOT NULL ,  

Any help would be appreciated.

A: 

What about this?

select delay 
    from table_name, 
         (select id, max(sent), ip from table_name group by ip) innertable 
   where innertable.id = table_name.id;

Not 100% sure I understood what you want as a result set, so I just picked delay.

Dante617
Well that just proves I've still got a lot to learn, considering I didn't even know that was possible... my query ended up looking like this: SELECT delay, ip FROM status, (SELECT id, max(sent) FROM status group by ip) innertable WHERE innertable.id = status.id That gives me plenty more to google... thanks.
Troy Knapp
Sorry, i thought this was correct, but I realized it was only returning my two first records.
Troy Knapp
Does the inner query (select id, max(sent), ip from table_name group by ip) give you the results you expect. I'm assuming you want one row in this result set for each IP address. Is that correct?
Dante617
Yes the inner query works as intended... it, of course, won't fulfill my requirement #2.After checking out "nested queries" I devised this, which works:SELECT ip, delay, sent FROM status WHERE sent IN (SELECT max(sent) FROM status GROUP BY ip), but I'm not sure if it's the best method possible, especially as my tables grow.
Troy Knapp
Can you help me understand why it doesn't fulfill requirement #2? Do new servers not get an entry in this table?
Dante617
Sorry, I wasn't clear in my question, I just edited it to make it better. The problem is that I need to know which servers are available to do work. If i group by IP, then that tells me which servers were EVER available, not necessarily the servers that are available at the time this query is ran.
Troy Knapp
A: 

After some googling, and some testing, this is the best answer I've found thus so far:

    SELECT ip, id, delay, stat_sent
    FROM status
    WHERE stat_sent > DATE_SUB( NOW( ) , INTERVAL 1 MINUTE )
    AND stat_sent
    IN (

        SELECT max( stat_sent )
        FROM status GROUP BY stat_ip
    )

Modified my answer now it limits the scope of the results to servers that have been updated in the last minute.

Troy Knapp