Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Problem z zapytaniem - liczenie odległości w promieniu od punktu - Harvestine formula, Jak wyciągnąć z bazy odpowiednie wartości do wzoru
Kulfon
post
Post #1





Grupa: Zarejestrowani
Postów: 45
Pomógł: 2
Dołączył: 24.12.2010

Ostrzeżenie: (0%)
-----


Cześć! Męczę się i męczę i chyba nie dojdę do tego jak powinno to być...

Znalazłem/wymyśliłem kilka innych rozwiązań ale traktuję je póki co jako drogę na około, a nie prawdiłową drogę działania dlatego chciałbym zapytać jeszcze tutaj - moze uda się to zrobić jak należy, a nie na około.

Chcę liczyć odległość od punktu. Na to mamy odpowiedni wzór. Zapytanie do bazy też nie powinno przysparzać problemów ale tutaj sprawa się komplikuje. Otóż postawione na Wordpressie. I moje pytanie odnosi się tylko do zapytania. Tabela wygląda tak:
id post_id meta_key meta_value
640 11 lat 50.0952545
641 11 lng 20.078393600000027
642 11 address Kwiatowa 12
(tabela wp_postmeta)

Czyli ogólnie to co potrzebuję to:
- wyciągnąć z bazy wartości lat i lng
- policzyć dystans
- tam gdzie dystans jest mniejszy niż podany do zapytania zwrócić np. pole address

Na moment obecny mam takie coś:
  1. $wpdb->get_results(sprintf("SELECT meta_value, post_id, ( 3959 * acos( cos( radians('%s') ) * cos( radians( '%s' ) ) * cos( radians( '%s' ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( '%s' ) ) ) )
  2. AS distance FROM wp_postmeta HAVING distance < '%s' ORDER BY distance LIMIT 0 , 200",
  3. mysql_real_escape_string($center_lat), // podana przez usera lat
  4. $wpdb->get_var("SELECT meta_value FROM wp_postmeta WHERE meta_key = 'lat'"), //brana z bazy wartosc lat
  5. $wpdb->get_var("SELECT meta_value FROM wp_postmeta WHERE meta_key = 'lng'"), //brana z bazy wartosc lng
  6. mysql_real_escape_string($center_lng), // podana przez usera lng
  7. mysql_real_escape_string($center_lat), podana przez usera lat
  8. $wpdb->get_var("SELECT meta_value FROM wp_postmeta WHERE meta_key = 'lat'"), //brana z bazy lat
  9. mysql_real_escape_string($radius)))//podany przez usera dystans


I nie wiem jak to doprowadzić do działania. Ogólnie wydaje mi się, że błąd popełniłem przy wybieraniu wlasnie z bazy tych lat i lng natomiast nie do końca wiem jak to zrobić. Czy mógłby mi ktoś powiedzieć jak powinno wyglądać prawidłowe zapytanie?




Edit:
Tak, siedzenie po nocach nie pomaga... Tutaj powinien być jakiś INNER JOIN zamiast sprintf'a prawda? (IMG:style_emoticons/default/biggrin.gif)

Ten post edytował Kulfon 18.02.2014, 14:01:26
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 12)
mar1aczi
post
Post #2





Grupa: Zarejestrowani
Postów: 731
Pomógł: 141
Dołączył: 9.05.2011
Skąd: śląskie

Ostrzeżenie: (0%)
-----


Możesz wystawić zrzut kawałka tej tabeli dla 5-10 postów.
Go to the top of the page
+Quote Post
Kulfon
post
Post #3





Grupa: Zarejestrowani
Postów: 45
Pomógł: 2
Dołączył: 24.12.2010

Ostrzeżenie: (0%)
-----


Mam 1 testowy post. Było ich więcej ale na moment obecny działam na jednym. Wygląda to tak:

  1. --
  2. -- Struktura tabeli dla tabeli `wp_postmeta`
  3. --
  4.  
  5. CREATE TABLE `wp_postmeta` (
  6. `meta_id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  7. `post_id` bigint(20) UNSIGNED NOT NULL DEFAULT '0',
  8. `meta_key` varchar(255) DEFAULT NULL,
  9. `meta_value` longtext,
  10. PRIMARY KEY (`meta_id`),
  11. KEY `post_id` (`post_id`),
  12. KEY `meta_key` (`meta_key`)
  13. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  14.  
  15. --
  16. -- Zrzut danych tabeli `wp_postmeta`
  17. --
  18.  
  19. INSERT INTO `wp_postmeta` (`meta_id`, `post_id`, `meta_key`, `meta_value`) VALUES
  20. (411, 75, 'name', 'Miejsce 1'),
  21. (412, 75, 'address', 'Dywizjonu 303 11/505 30-123 KrakĂłw'),
  22. (420, 75, 'publicOrPrivate', 'public'),
  23. (423, 75, 'telefon', '123123123'),
  24. (426, 75, 'custom_logo', 'custom_logo_75.jpg'),
  25. (427, 75, 'custom_photo1', 'custom_photo1_75.jpg'),
  26. (428, 75, 'custom_photo2', 'custom_photo2_75.jpg'),
  27. (658, 75, 'lat', '50.08491009999999'),
  28. (659, 75, 'lng', '20.003797200000008');
Go to the top of the page
+Quote Post
mar1aczi
post
Post #4





Grupa: Zarejestrowani
Postów: 731
Pomógł: 141
Dołączył: 9.05.2011
Skąd: śląskie

Ostrzeżenie: (0%)
-----


W jednym wierszu post_id, lat, lng i odległość (musisz podstawić do wzoru):
  1. SELECT r.post_id,
  2. sum(IF(meta_key = 'lat', meta_value, 0)) AS lat,
  3. sum(IF(meta_key = 'lng', meta_value, 0)) AS lng,
  4. 'obliczenia' AS distance
  5. FROM (
  6. SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE meta_key IN ('lat', 'lng')) r
  7. GROUP BY r.post_id

Z resztą powinieneś sobie poradzić (IMG:style_emoticons/default/wink.gif)

Ten post edytował mar1aczi 18.02.2014, 14:34:22
Go to the top of the page
+Quote Post
Kulfon
post
Post #5





Grupa: Zarejestrowani
Postów: 45
Pomógł: 2
Dołączył: 24.12.2010

Ostrzeżenie: (0%)
-----


Aaa czekaj w sensie jak podstawić: "W jednym wierszu post_id, lat, lng i odległość (musisz podstawić do wzoru):".
O tyle o ile wydaje mi się, że rozumiem zapytanie to nie wiem o co Ci chodziło (IMG:style_emoticons/default/biggrin.gif)

Ten post edytował Kulfon 18.02.2014, 14:39:53
Go to the top of the page
+Quote Post
mar1aczi
post
Post #6





Grupa: Zarejestrowani
Postów: 731
Pomógł: 141
Dołączył: 9.05.2011
Skąd: śląskie

Ostrzeżenie: (0%)
-----


Tam gdzie ja wstawiłem 'obliczenia' musisz zastosować wzór na odległość między punktami. Współrzędne punktu od użytkownika pobierasz przed wykonaniem zapytania i "wkładasz" do wzoru w zapytaniu z odpowiednim where/having.

Ten post edytował mar1aczi 18.02.2014, 14:43:11
Go to the top of the page
+Quote Post
Kulfon
post
Post #7





Grupa: Zarejestrowani
Postów: 45
Pomógł: 2
Dołączył: 24.12.2010

Ostrzeżenie: (0%)
-----


I wyszło coś takiego:
  1. sprintf("SELECT r.post_id,
  2. sum(IF(meta_key = 'lat', meta_value, 0)) AS lat,
  3. sum(IF(meta_key = 'lng', meta_value, 0)) AS lng,
  4. ( 3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) )
  5. AS distance HAVING distance < '%s'
  6. FROM (SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE meta_key IN ('lat', 'lng')) r
  7. GROUP BY r.post_id LIMIT 0, 20",


Natomiast wynik zapytania to pusta tablica - nic mi nie zwraca :/

Dobra... to szukam błędu
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'HAVING distance < '100'
FROM (SELECT post_id, meta_key, meta_value FROM wp_postm' at line 5

Ten post edytował Kulfon 18.02.2014, 14:55:23
Go to the top of the page
+Quote Post
mar1aczi
post
Post #8





Grupa: Zarejestrowani
Postów: 731
Pomógł: 141
Dołączył: 9.05.2011
Skąd: śląskie

Ostrzeżenie: (0%)
-----


Podstaw wartości "od użytkownika" ręcznie do zapytania i sprawdź czy zapytanie wykona Ci się poprawnie "z palca" np. w phpmyadmin.
Go to the top of the page
+Quote Post
Kulfon
post
Post #9





Grupa: Zarejestrowani
Postów: 45
Pomógł: 2
Dołączył: 24.12.2010

Ostrzeżenie: (0%)
-----


To niestety też jest błąd - dokładnie taki sam
Przykładowo zapytanie wygląda tak:
  1. SELECT r.post_id,
  2. sum(IF(meta_key = 'lat', meta_value, 0)) AS lat,
  3. sum(IF(meta_key = 'lng', meta_value, 0)) AS lng,
  4. ( 3959 * acos( cos( radians(50.0952545) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(20.078393600000027) ) + sin( radians(50.0952545) ) * sin( radians( lat ) ) ) )
  5. AS distance HAVING distance < 100
  6. FROM (SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE meta_key IN ('lat', 'lng')) r
  7. GROUP BY r.post_id LIMIT 0, 20


Ok, delikatnie zmieniłem zapytanie:

  1. SELECT r.post_id,
  2. sum(IF(meta_key = 'lat', meta_value, 0)) AS lat,
  3. sum(IF(meta_key = 'lng', meta_value, 0)) AS lng,
  4. ( 3959 * acos( cos( radians(50.0952545) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(20.078393600000027) ) + sin( radians(50.0952545) ) * sin( radians( lat ) ) ) )
  5. AS distance
  6. FROM (SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE meta_key IN ('lat', 'lng')) r HAVING distance < 100
  7. GROUP BY r.post_id LIMIT 0, 20


i teraz jeszcze:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'GROUP BY r.post_id' at line 7
Go to the top of the page
+Quote Post
mar1aczi
post
Post #10





Grupa: Zarejestrowani
Postów: 731
Pomógł: 141
Dołączył: 9.05.2011
Skąd: śląskie

Ostrzeżenie: (0%)
-----


Tak:
  1. SELECT rr.post_id, rr.lat, rr.lng,
  2. ( 3959 * acos( cos( radians(50.0952545) ) * cos( radians( rr.lat ) ) * cos( radians( rr.lng ) - radians(20.078393600000027) ) + sin( radians(50.0952545) ) * sin( radians( rr.lat ) ) ) ) AS distance
  3. FROM (
  4. SELECT r.post_id,
  5. sum(IF(meta_key = 'lat', meta_value, 0)) AS lat,
  6. sum(IF(meta_key = 'lng', meta_value, 0)) AS lng
  7. FROM (SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE meta_key IN ('lat', 'lng')) r
  8. GROUP BY r.post_id) rr
  9. HAVING ( 3959 * acos( cos( radians(50.0952545) ) * cos( radians( rr.lat ) ) * cos( radians( rr.lng ) - radians(20.078393600000027) ) + sin( radians(50.0952545) ) * sin( radians( rr.lat ) ) ) ) < 100

Poczytaj o składni zapytań sql, przyda Ci się taka lektura (IMG:style_emoticons/default/wink.gif)

Ten post edytował mar1aczi 18.02.2014, 15:29:27
Go to the top of the page
+Quote Post
Kulfon
post
Post #11





Grupa: Zarejestrowani
Postów: 45
Pomógł: 2
Dołączył: 24.12.2010

Ostrzeżenie: (0%)
-----


Tak, racja trochę zaniedbałem bazy danych (IMG:style_emoticons/default/wstydnis.gif)

Hmm tego kodu nie można zmienić na taki? Czemu powtarzać wzór skoro mamy 'AS distance'. To poniżej również działa (IMG:style_emoticons/default/smile.gif)

  1. SELECT rr.post_id, rr.lat, rr.lng,
  2. ( 3959 * acos( cos( radians(50.0952545) ) * cos( radians( rr.lat ) ) * cos( radians( rr.lng ) - radians(20.078393600000027) ) + sin( radians(50.0952545) ) * sin( radians( rr.lat ) ) ) ) AS distance
  3. FROM (
  4. SELECT r.post_id,
  5. sum(IF(meta_key = 'lat', meta_value, 0)) AS lat,
  6. sum(IF(meta_key = 'lng', meta_value, 0)) AS lng
  7. FROM (SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE meta_key IN ('lat', 'lng')) r
  8. GROUP BY r.post_id) rr
  9. HAVING distance < 100


Jeszcze jedno małe pytanko. (IMG:style_emoticons/default/smile.gif)

O tyle o ile dane z innej tabeli wyciągnę sobie dodając na koniec tego zapytania:
  1. LEFT JOIN `wp_ratings` ON (rr.post_id = `wp_ratings`.post_id)
i po pierwszym SELECT nazwa_kolumny
to zupełnie nie wiem jak dzięki temu zapytaniu z postu powyżej wyciągnąć wartość dla innego meta_key np wartość dla address - czyli żeby oprócz lat i lng jak do tej pory wypluwało również address...
Go to the top of the page
+Quote Post
mar1aczi
post
Post #12





Grupa: Zarejestrowani
Postów: 731
Pomógł: 141
Dołączył: 9.05.2011
Skąd: śląskie

Ostrzeżenie: (0%)
-----


Np.
  1. SELECT rr.post_id, rr.lat, rr.lng,
  2. ( 3959 * acos( cos( radians(50.0952545) ) * cos( radians( rr.lat ) ) * cos( radians( rr.lng ) - radians(20.078393600000027) ) + sin( radians(50.0952545) ) * sin( radians( rr.lat ) ) ) ) AS distance, (SELECT meta_value FROM wp_postmeta p WHERE p.post_id = rr.post_id AND p.meta_key = 'address') AS address
  3. FROM (
  4. SELECT r.post_id,
  5. sum(IF(meta_key = 'lat', meta_value, 0)) AS lat,
  6. sum(IF(meta_key = 'lng', meta_value, 0)) AS lng
  7. FROM (SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE meta_key IN ('lat', 'lng')) r
  8. GROUP BY r.post_id) rr
  9. HAVING distance < 100
Go to the top of the page
+Quote Post
Kulfon
post
Post #13





Grupa: Zarejestrowani
Postów: 45
Pomógł: 2
Dołączył: 24.12.2010

Ostrzeżenie: (0%)
-----


No tak, próbowałem w ten sposób:
  1. SELECT meta_value FROM wp_postmeta WHERE meta_key = 'address' AS address


Wielkie dzięki (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 23.08.2025 - 01:34