Improve company productivity with a Business Account.Sign Up

x
?
Solved

find locations near zip code

Posted on 2006-07-20
6
Medium Priority
?
355 Views
Last Modified: 2008-02-26
Hi,

We have an intranet application that looks up our retail locations based on the customers zip code (so we can direct them to the nearest store). It's actually an MS SQL stored procedure.

We want to port this to a MySQL/PHP application. Here is the stored procedure that determines the nearest locations:

------------------------------------------------------
CREATE Procedure sp_RetailerDistance

      (
            @pLAT float,
            @pLNG float
      )


As
SELECT TOP 20
    ARX_RetailerLocatorList.CustomerNumber,
    ARX_RetailerLocatorList.ShipToCode,
    ARX_RetailerLocatorList.CustomerName,
    ARX_RetailerLocatorList.AddressLine1,
    ARX_RetailerLocatorList.City,
    ARX_RetailerLocatorList.State,
    ARX_RetailerLocatorList.ZipCode,
    ARX_RetailerLocatorList.PhoneNumber,
    ZipLocation.LAT,
    ZipLocation.LNG,
    STR(3959 * acos(sin(LAT/57.3)*sin(@pLAT/57.3) + cos(LAT/57.3) * cos(@pLAT/57.3) * cos(@pLNG/57.3 - LNG/57.3)),7,1) As Distance
FROM
    dbo.ARX_RetailerLocatorList
    INNER JOIN
    dbo.ZipLocation
    ON
    LEFT(dbo.ARX_RetailerLocatorList.ZipCode, 5) = dbo.ZipLocation.ZIP_CODE
ORDER BY
    Distance ASC

return
GO
----------------------------------------------------

I guess @pLAT and @pLNG are passed in as parameters? IF so, then I should figure out how those values are determined first... Basically I would like suggestions or a solution on how to port this to mysql. Maybe there's already a solution out there that does something similar. I would rather not do it as a stored procedure (and would prefer a php-based solution), but whatever works is good for me...

Thanks!
0
Comment
Question by:MaritimeSource
  • 2
  • 2
  • 2
6 Comments
 

Author Comment

by:MaritimeSource
ID: 17149051
I've determined there's a "ziplocation" table that has the following columns:

zip, city, state, lng, lat

So the script first gets the lng and lat based on the zip provided. Then it passes those to the stored procedure.
0
 
LVL 9

Expert Comment

by:Rob_Jeffrey
ID: 17149153
The stored procedure does take the Latitude and Logitude from the other table as parameters.
You can write this as a PHP function relatively easily.  The first part would be to get the data into an equivilantly structured MySQL tables.

The newest versions of MySQL server allow for stored procedures as well so this could be ported directly into the MySQL server as a stored procedure.
0
 

Author Comment

by:MaritimeSource
ID: 17149181
Right, but stored procedure syntax is different amongst various db's right? This is MS SQL SERVER:

STR(3959 * acos(sin(LAT/57.3)*sin(@pLAT/57.3) + cos(LAT/57.3) * cos(@pLAT/57.3) * cos(@pLNG/57.3 - LNG/57.3)),7,1) As Distance

Would that work directly in MYSQL?
0
The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

 
LVL 9

Assisted Solution

by:Rob_Jeffrey
Rob_Jeffrey earned 400 total points
ID: 17149267
MySQL does have mathematical functions for COS, aCOS, and SIN so it should work with minimal changes.
The function may need some tweaking if there is a sign order difference - but it doesn't look like it.
These functions have been available since at lease MySQL 4.0.3.
0
 
LVL 6

Accepted Solution

by:
SysTurn earned 1600 total points
ID: 17152451
The calcualtions you do will have invalid results according to the calculations shown here: http://mathforum.org/library/drmath/view/51711.html

The stored procedure shold be rewritten like this:

STORED PROCEDURE:
==================

CREATE Procedure sp_RetailerDistance

     (
          @pLAT float,
          @pLNG float
     )


As
SELECT TOP 20
    ARX_RetailerLocatorList.CustomerNumber,
    ARX_RetailerLocatorList.ShipToCode,
    ARX_RetailerLocatorList.CustomerName,
    ARX_RetailerLocatorList.AddressLine1,
    ARX_RetailerLocatorList.City,
    ARX_RetailerLocatorList.State,
    ARX_RetailerLocatorList.ZipCode,
    ARX_RetailerLocatorList.PhoneNumber,
    ZipLocation.LAT,
    ZipLocation.LNG,
    CASE
        WHEN (LAT = @pLAT AND LNG = @pLNG) THEN 0
        WHEN ((SIN(LAT / 57.29577951) * SIN(@pLAT / 57.29577951)) + (COS(LAT / 57.29577951) * COS(@pLAT / 57.29577951) * COS((LNG / 57.29577951) - (@pLNG /57.29577951))) > 1) THEN STR(3963.1 * ACOS(1), 7, 1)
        ELSE STR(3963.1 * ACOS(SIN(LAT / 57.29577951) * SIN(@pLAT / 57.29577951)) + (COS(LAT / 57.29577951) * COS(@pLAT / 57.29577951) * COS((LNG / 57.29577951) - (@pLNG /57.29577951))), 7, 1)
    END AS Distance
FROM
    dbo.ARX_RetailerLocatorList
    INNER JOIN
    dbo.ZipLocation
    ON
    LEFT(dbo.ARX_RetailerLocatorList.ZipCode, 5) = dbo.ZipLocation.ZIP_CODE
ORDER BY
    Distance ASC

return
GO



And the PHP function can be something like this:

function RetailerDistance($pLAT, $pLNG)
{
    $SQL = 'SELECT
                ARX_RetailerLocatorList.CustomerNumber,
                ARX_RetailerLocatorList.ShipToCode,
                ARX_RetailerLocatorList.CustomerName,
                ARX_RetailerLocatorList.AddressLine1,
                ARX_RetailerLocatorList.City,
                ARX_RetailerLocatorList.State,
                ARX_RetailerLocatorList.ZipCode,
                ARX_RetailerLocatorList.PhoneNumber,
                ZipLocation.LAT,
                ZipLocation.LNG,
                CASE
                    WHEN (LAT = ' . $pLAT . ' AND LNG = ' . $pLNG . ') THEN 0
                    WHEN ((SIN(LAT / 57.29577951) * SIN(' . $pLAT . ' / 57.29577951)) + (COS(LAT / 57.29577951) * COS(' . $pLAT . ' / 57.29577951) * COS((LNG / 57.29577951) - (' . $pLNG . ' /57.29577951))) > 1) THEN TRUNCATE(3963.1 * ACOS(1), 1)
                    ELSE TRUNCATE(3963.1 * ACOS(SIN(LAT / 57.29577951) * SIN(' . $pLAT . ' / 57.29577951)) + (COS(LAT / 57.29577951) * COS(' . $pLAT . ' / 57.29577951) * COS((LNG / 57.29577951) - (' . $pLNG . ' /57.29577951))), 1)
                END AS Distance
            FROM
                ARX_RetailerLocatorList
                INNER JOIN
                ZipLocation
                ON (LEFT(ARX_RetailerLocatorList.ZipCode, 5) = ZipLocation.ZIP_CODE)
            ORDER BY
                Distance ASC
            LIMIT 0, 20';
               
    //
    // EXECUTE THE SQL AND RETURN ITS RESULT
    //
}

If you still want to work with the same calculations you use, It will be easy for you now to edit the SQL query.


Kind Regards
Bakr
0
 
LVL 6

Expert Comment

by:SysTurn
ID: 17154467
Thanks for the A ;) Glad to hear that your problem has been solved.

Kind Regards
Bakr
0

Featured Post

The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

There are times when I have encountered the need to decompress a response from a PHP request. This is how it's done, but you must have control of the request and you can set the Accept-Encoding header.
This holiday season, we’re giving away the gift of knowledge—tech knowledge, that is. Keep reading to see what hacks, tips, and trends we have wrapped and waiting for you under the tree.
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.

606 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question