简体   繁体   中英

how to update by the closest numeric value

I have two tables Cities_no_iata this table have columns (CountryID,iata_code,latitude,longtiute)

Cities_iata this table have columns (CountryID,iata_code,latitude,longtiute)

The first table contains the cities which haven't iata_code so all rows in iata_code column is null

The second table contains the cities which have iata_code

So I want to copy the closest city iata_code to the city which haven't iata_code ,I think to do this by 2 things

1- The closest (latitude and longitude) for the two cities

2- The same CountryID for the the two cities .

Update Cities_iata
JOIN Cities_no_iata USING (CountryID)
Where ABS( cities_iata.latitude)= ABS(Cities_no_iata.latitude)
AND  ABS( cities_iata.longitude)= ABS(Cities_no_iata.longitude)
AND cities_iata.CountryID = Cities_no_iata.country_id
set(   Cities_no_iata.iata_code =cities_iata.iata_code);

but dont work

This query approximates the distance using a Euclidean formula. Actually, even for the approximation, you would want to take into account that unit difference in latitude is different than for longitude, depending on the latitude -- this requires multiplying the latitude difference by the cosine.

However, I'm going to assume the question is really about finding the closest, not about the specific distance formula. The following query returns the nearest iata code for cities in the table with none:

select cni.*,
       (select iata_code
        from cities_iata ci
        order by pow(cia.latitude - ci.latitude, 2) + pow(cia.longitude - ci.longitude, 2)
        limit 1
       ) as new_iata_code
from cities_no_iata cni;

We can turn this into an update using join :

update cities_no_iata join
       (select cni.*,
               (select iata_code
                from cities_iata ci
                order by pow(cia.latitude - ci.latitude, 2) + pow(cia.longitude - ci.longitude, 2)
                limit 1
               ) as new_iata_code
        from cities_no_iata cni
       ) upd
       on cities_no_iata.latitude = upd.latitude and
          cities_no_iata.longitude = upd.longitude
     set iata_code = upd.iata_code;

Two comments. You can put any distance function you like in the order by clause, so this should generalize to be what you want. Second, you should have a unique identifier for each row, so the final join can be done one the city identifier rather than on latitude and longitude.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM