2016-10-29 18 views
6

Czytałem już w promieniu i mysql i jestem bardzo zdezorientowany, jak dokładnie zaimplementować kod z wieloma zmiennymi wyszukiwania, więc może ktoś mi to zepsuje.Jak mogę użyć funkcji promienia PHP z wieloma zmiennymi?

Moja baza danych zawiera następujące tabele:

IDX | typ | cena | item_desc | s_lat | s_long | data utworzenia

Oto mój obecny kod.

$search_origin_radius = "200"; 
$search_dest_radius = "100"; 
$search_origin_lat = "37.2629742"; 
$search_origin_long = "-98.286158"; 
$search_dest_lat = "37.2629742"; 
$search_dest_long = "-98.286158"; 
$type = "consumers"; 
$price = "100"; 

$sql = "SELECT * FROM products WHERE `price` = '$price'"; 

if($type && !empty($type)) 
{ 
    $sql .= " AND `type` = '$type'";  
} 

Wszystko znalazłem do tej pory mówi używać:

SELECT id, (3959 * acos(cos(radians(37)) * cos(radians(latitude)) 
    * cos(radians(longitude) - radians(-122)) + sin(radians(37)) * sin(radians(lat)))) AS distance 
FROM myTable 
HAVING distance < 50 
ORDER BY distance 

Ale jestem bardzo mylić, w jaki sposób zaimplementować go do $search_origin_radius i $search_dest_radius. Zasadniczo próbuję znaleźć wszystko, co jest na sprzedaż w przedziale cenowym i promieniu wokół dwóch miast.

Przykład Chcę znaleźć wszystko za 100 USD w Oklahoma City, OK w promieniu 200 mil i Kansas City, MO w promieniu 100 mil.

EDYCJA ** Zgodnie z sugestią dodano to jako funkcję zapisaną.

function Calc_Distance($latitudeFrom, $longitudeFrom, $latitudeTo,   $longitudeTo, $earthRadius = 3959) 
{ 
    // convert from degrees to radians 
    $latFrom = deg2rad($latitudeFrom); 
    $lonFrom = deg2rad($longitudeFrom); 
    $latTo = deg2rad($latitudeTo); 
    $lonTo = deg2rad($longitudeTo); 

    $latDelta = $latTo - $latFrom; 
    $lonDelta = $lonTo - $lonFrom; 

    $angle = 2 * asin(sqrt(pow(sin($latDelta/2), 2) + 
    cos($latFrom) * cos($latTo) * pow(sin($lonDelta/2), 2))); 
    return $angle * $earthRadius; 
} 

Korzystanie nowe zapytanie, ale nadal nic nie pokazuje się:

$sql = " 
SELECT * 
FROM products 
WHERE Calc_Distance(s_lat, s_long, $search_origin_lat, $search_origin_long) < 200 
    AND Calc_Distance(s_lat, s_long, $search_dest_lat, $search_dest_long) < 100 
    AND price = $price 
"; 
+0

tak, aby funkcja cos/sin działała, ale chcesz użyć '$ search_origin_radius'? Może zdjęcie lub przykładowe dane mogą pomóc w zrozumieniu, czego chcesz. –

+0

Nie jestem pewien, czy rozumiem, o co prosisz. Nie wiem, jak zaimplementować funkcję cos/sin do mojego bieżącego zapytania sql. – Jayce

+0

czy możesz pokazać mi, jaki obszar cię interesuje? –

Odpowiedz

0

Napisz zapisanego funkcję, która pobiera dwie pary lat i LNG, i zwraca odległość.

$sql = " 
SELECT ... 
    FROM MyTbl 
    WHERE Distance(s_lat, s_long, $search_origin_lat, $search_origin_long) < 200 
     AND Distance(s_lat, s_long, $search_dest_lat, $search_dest_long) < 100 
     AND price = $price 
"; 

Lub przeliteruj wyrażenie dwukrotnie.

+0

Więc odległość byłaby moją funkcją przechowywaną poprawnie ? Zobacz zaktualizowany kod, ponieważ wraca z niczym w promieniu. – Jayce

+0

Nie używaj zmiennych $ w funkcji. –

+0

Nie jestem pewien, czy rozumiem co masz na myśli? Przykład? – Jayce

5

Oklahoma City i Kansas City oddalone są od siebie o prawie 300 mil.

Istnieje bardzo mało ziemi, które można uznać zarówno w promieniu 200 mil od Oklahoma City AND pod 100 mil od Kansas City, więc nie jestem zaskoczony, że zapytanie nie zwraca żadnych wyników.

Może chciałeś OR logiki tutaj ..

SELECT id 
    FROM products 
WHERE (*Oklahoma City distance calc miles* < 200 
    OR *Kansas City distance calc miles* < 100) 
    AND price = 100; 

..or mogłeś UNION ALLSELECT dla każdego miasta:

SELECT id, 'Oklahoma City' as city 
    FROM products 
WHERE *Oklahoma City distance calc miles* < 200 
    AND price = 100 

UNION ALL 

SELECT id, 'Kansas City' 
    FROM products 
WHERE *Kansas City distance calc miles* < 100 
    AND price = 100; 

Osobiście skłaniam się ku drugiej, jak to jest łatwe zbudować kod i podać, w którym mieście produkt jest starannie dobrany.

Chociaż jak wskazano przez @PaulSpiegel to (niezmodyfikowane) może zwrócić kilka produktów więcej niż raz, jeśli obszary wyszukiwania się przecinają.

+0

Cóż, na co mam zamiar cokolwiek sprzedać w promieniu 200 mil od Oklahoma City i wszystko, co sprzedam w ciągu 100 w promieniu mili od Kansas City. Więc jeśli coś jest w Oklahoma City, pokaż to i czy jest coś, co pokazuje Kansas City.Tak więc można mieć zero wyników, podczas gdy drugi robi. Jak teraz w moim DB, umieściłem 3 rzeczy na sprzedaż w Kansas City i 2 w Oklahoma City. Wiem więc, że w tym zakresie są rzeczy, a jeśli zrobię jedno zapytanie dla każdego miasta, to pokażą wyniki, ale nie oba razem. Jeśli to ma sens? – Jayce

+1

Tak, rozumiem, ale jeśli "AND" razem dwa warunki na odległość mówisz, że oba muszą być prawdziwe! Tak więc albo "LUB" warunki dwóch odległości razem lub użyj "UNION ALL", aby połączyć wyniki. – Arth

+0

To jest właściwa odpowiedź. OP nie powinien używać AND. To, co opisują, zwróci tylko coś, co jest zasadniczo w połowie drogi z KC do OKC, które może mieć przypadek użycia, ALE odległość musiałaby być zmienna, a nie ustalona na 200 mil, ponieważ problem został rozwiązany. – kyle

0

Jeśli używasz MySQL w wersji 5.7 można użyć to Przestrzennego benzynowe Funkcje a dokładniej ST_Distance_Sphere. W ten sposób uzyskasz wynik w metrach, a stamtąd możesz łatwo obliczyć w milach.

Jeśli wersja MySQL 5.6.1 można użyć ST_Distance funkcję jak w tym MySQL Fiddle example

SELECT *,ST_Distance(POINT(`s_lat`,`s_long`), POINT(35.5857,-97.4885))*68.925*1.60934 AS `exact_distance` 
FROM `entries` WHERE `price`=100 
HAVING `exact_distance`<=200; 

Zauważysz 2 stałych (68.925 i 1.60934). Pierwsza z nich zamieni wynik ST_Distance na mile Druga (po dodaniu) zamieni ją na kilometry W powyższym przykładzie ST_Distance służy do uzyskania odległości punktu geograficznego od Oklahoma City. Jeśli chcesz dodać kolejne miasto do zapytania SELECT, możesz użyć czegoś podobnego.

SELECT *,ST_Distance(POINT(`s_lat`,`s_long`), POINT(35.5857,-97.4885))*68.925 AS `exact_distance_from_Oklahoma_City`, 
ST_Distance(POINT(`s_lat`,`s_long`), POINT(39.127562,-94.598810))*68.925 AS `exact_distance_from_Kansas_City` 
FROM `entries` WHERE `price`=100 
HAVING `exact_distance_from_Oklahoma_City`<=200 
AND `exact_distance_from_Kansas_City`<=100; 
Powiązane problemy