views:

101

answers:

1

I've got a huge bunch of flights travelling between airports.

Each airport has an ID and (x,y) coordinates.

For a given list of flights, I want to find the northernmost (highest x) airport visited.


Here's the query I'm currently using:

SELECT name,iata,icao,apid,x,y 
  FROM airports 
 WHERE y=(SELECT MAX(y) 
            FROM airports AS a
               , flights AS f 
           WHERE (f.src_apid=a.apid OR f.dst_apid=a.apid) AND [condition]
         )

This works beautifully and reasonably fast as long as y is unique, but fails once it isn't. What I'd want to do instead is find the MAX(y) in the subquery, but return the unique apid for the airport with the highest y. Any suggestions?

+1  A: 

third attempt, using assumed user (userid,name) table

select u.name, ap.name
     , ap.iata
     , ap.icao
     , ap.apid
     , ap.x
     , max(ap.y)  
  from users u
     , airports ap
     , flights f
 where u.userid=f.userid
   and (   f.src_apid=ap.apid 
        OR f.dst_apid=ap.apid
       )
group by u.name, ap.name,ap.iata,ap.icao,ap.apid,ap.x 

you can now restrict the query to the one user you are interested in ..

comment on GROUP BY:

  • strictly speaking MySQL would allow me to write that group by as 'group by u.name, ap.name'.
  • Other SQL dialects don't, they ask that all selected fields that are not aggregated be in the GROUP BY statement.
  • So I tend to be 'chicken' when selecting my GROUP BY fields ...
lexu
Should have been a little clearer there: so there are cases like Honolulu which are simultaneously a civilian airport (code PHNL) and a military airfield (code PHIK), and thus show up as two distinct airports that happen to have the same coordinates. Your query will still return both.
jpatokal
OK, that will be a bit harder .. which one of the two airports would you want to see? Is there a sorting criterion to be applied? Or is apid (=AirPortID) the same for PHIK and PHNL?
lexu
apid is the unique key for airports, so PHIK and PHNL have different ones, and I'd need to see the one that originally matched -- that is, the apid of the airport that's equal to f.src_apid or f.dst_apid.A more concrete example: User X has one flight (select from flights where f.uid=X) from Honolulu-PHNL to Sydney, and I want to know User X's northernmost airport. The answer should be Honolulu-PHNL, not Hickam AFB (PHIK).
jpatokal
Do you have a table with the users? If you could join against that then you could achieve your goal using a group by.
lexu
Yes, there is a user table, but the query above is unusably slow -- according to describe, it starts off with a temporary table and filesort on 342,118 rows. =(
jpatokal