Results 1 to 9 of 9

Thread: Access Distance Issue

  1. #1

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,844

    Access Distance Issue

    I'm trying to get the record in an Access database table holding known locations that is closest to some waypoint. Normally, to find the distance between two geographic points, you would use the Haversine formula, but that isn't possible in an Access query because some necessary math formulas are not available. That's no big deal, because I can readily narrow the search down to just a handful of points, but that is proving odd.

    My idea was to get some fields, and the smallest distance using the Pythagorean Theorem:

    Code:
    SELECT TOP 1 HName,RouteGUID,Lat_WGS84,Lon_WGS84, MIN(SQR(
                                                                    ((" & latitude.ToString & " - Lat_WGS84) * (" & latitude.ToString & " - Lat_WGS84))
                                                                    + ((" & longitude.ToString & " - Lon_WGS84) * (" & longitude.ToString & " - Lon_WGS84))
                                                                    )) AS Dist
    		                                FROM GIS_Routing
                                            WHERE GIS_Routing.LLID = '" & LLID & "'
                                            GROUP BY HName, RouteGUID,Lat_WGS84,Lon_WGS84"
    For the sake of discussion, the query could be simplified to:

    Code:
    SELECT TOP 1 HName,RouteGUID,Lat_WGS84,Lon_WGS84, MIN(Pythagoras) AS Dist
    		                                FROM GIS_Routing
                                            WHERE GIS_Routing.LLID = '" & LLID & "'
                                            GROUP BY HName, RouteGUID,Lat_WGS84,Lon_WGS84"
    That doesn't work, because Min appears to usually do nothing in this query. I get the records back in whatever order Access chooses.

    I also thought to use Order By, which would be simpler...except that I can't order by Dist (the alias I gave the column). I believe I COULD use Order By, so long as I was willing to write out that entire equation in the Order By statement. That's not hard to do, since I can copy and paste, but it seems terribly inefficient, as it seems like it would require that the calculation be performed twice.


    So, what is the best way to get the record with the smallest distance?
    My usual boring signature: Nothing

  2. #2
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,755

    Re: Access Distance Issue

    Wow. Access!
    Maybe, from what I read here: https://stackoverflow.com/questions/...correct-result
    You might get MIN to work if you use "Val" ,of course there is no environment anywhere I could test this.
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  3. #3

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,844

    Re: Access Distance Issue

    Access has many peculiarities. I had not seen that one. I don't believe it will work, but what the heck, might as well try it. The reason I don't believe it will work is that, while Min may not ensure things are a number (can't be an integer, as many of these will differ only by the fractional part), SQR certainly should. Therefore, SQR should serve the same purpose as Val in that example. Still, the only way to be certain is to test it.
    My usual boring signature: Nothing

  4. #4
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,043

    Re: Access Distance Issue

    In your original Query (or the second one), leave out the TOP 1 and put it in a Sub-Query using an ORDER BY there (!!) --> you receive ALL Datapoints Ordered acc. to your Criteria!
    And from the OUTER SELECT you grab the Data from the ordered Subselect and THEN apply your TOP 1

    Code:
    SELECT TOP 1 Your Fields Here.... FROM 
    (SELECT ID, blablabl,  MIN(Pythagoras) As DIST FROM MyTable WHERE SomeID=42 GROUP BY SomeFIelds ORDER BY MIN(Pythagoras))
    Though i dare say the performance might be poor depending on how many Datapoints the Subselect is really returning.
    IF the Subselect only returns a few hundred, you might not notice anything, if there are a few million datapoints though.....

    test test test it... as always
    Last edited by Zvoni; May 7th, 2025 at 01:35 AM.
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  5. #5

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,844

    Re: Access Distance Issue

    I had a design kind of like that earlier, but not quite like that. Specifically, it left out the Order By in the sub-query. As it turns out, the size will not be an issue. Though the table itself is large, that WHERE statement will drop the number of results down to between about 2 and two dozen, which should be trivial.
    My usual boring signature: Nothing

  6. #6

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,844

    Re: Access Distance Issue

    I simplified that a bit by just ordering by the Pythagorean result. I knew that was possible, I was just hoping it wasn't necessary. Seems like extra work. Perhaps the query engine optimizes away the double calculation, but perhaps not.
    My usual boring signature: Nothing

  7. #7
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,043

    Re: Access Distance Issue

    Quote Originally Posted by Shaggy Hiker View Post
    I simplified that a bit by just ordering by the Pythagorean result. I knew that was possible, I was just hoping it wasn't necessary. Seems like extra work. Perhaps the query engine optimizes away the double calculation, but perhaps not.
    Could be (untested) since the ORDER BY is the last operation of an SQL-statement, and at that point the calculated value is known.
    IIRC, in the ORDER BY you should be able to use the Alias of the „Field“
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  8. #8
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,043

    Re: Access Distance Issue

    I've just reread the Order of Execution for an SQL-Statement:

    • FROM and/or JOIN clause.
    • WHERE clause.
    • GROUP BY clause.
    • HAVING clause.
    • SELECT clause.
    • DISTINCT clause.
    • ORDER BY clause.
    • LIMIT and/or OFFSET clause.


    That said: You shouldn't need the Sub-select.
    The ORDER BY is the second-to-last, followed by the Limit (TOP X in Access/MS SQL).
    And i just did a test with SQLite: You can definitely use the Field-Alias of the Aggregate in the ORDER-Clause

    Code:
    SELECT TOP 1 HName,RouteGUID,Lat_WGS84,Lon_WGS84, 
    MIN(SQR(((" & latitude.ToString & " - Lat_WGS84) * (" & latitude.ToString & " - Lat_WGS84))
        + ((" & longitude.ToString & " - Lon_WGS84) * (" & longitude.ToString & " - Lon_WGS84)))) AS Dist
    FROM GIS_Routing
    WHERE GIS_Routing.LLID = '" & LLID & "'
    GROUP BY HName, RouteGUID,Lat_WGS84,Lon_WGS84
    ORDER BY Dist
    should do it.

    OTOH, it's MS Access we are talking about, so there....
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  9. #9

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,844

    Re: Access Distance Issue

    Yeah, I was thinking I could use the alias, but that does not work. That throws an exception about no value given for one or more parameters, so that alias...well, it is no longer an alias by the Order By phrase.

    In any case, it works with the full mess in the Order By statement. Whether it does the calculations twice or not, I can't say, but there are so few records returned that it doesn't really matter.
    My usual boring signature: Nothing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width