Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL] stworzenie zapytania SELECT
Forum PHP.pl > Forum > Bazy danych > MySQL
pawelt
Witam..
Mam problem ze stworzeniem zapytania SELECT (phpMyAdmin).
Chodzi o to, że posiadam tabelę z miejscowościami:

MIASTA
id_miasta (PK)
nazwa_miasta

drugą tabelę z trasami:

TRASY
id_trasy (PK)
start
koniec

oraz trzecią tabelę z miejscowościami pośrednimi na danej trasie:

PRZEZ
id_trasy (FK)
miasto_posrednie

W kolumnach "start" oraz "koniec" tabeli TRASY start=id_miasta oraz koniec=id_miasta.
Analogicznie w kolumnie "miasto_posrednie" tabeli PRZEZ miasto_posrednie=id_miasta.
Zależy mi na tym, aby miasta zawsze pobierać z jednej tabeli (MIASTA).

I jak teraz wyświetlić tabelę z prawdziwymi nazwami miejscowości na danej trasie?
Np. tak żeby otrzymać taki wynik:

start: Łódź ____ koniec: Lublin ____ miasto_posrednie: Warszawa
start: Łódź ____ koniec: Lublin ____ miasto_posrednie: Radom ____ miasto_posrednie: Puławy
...

Albo chociaż żeby wyświetlić tylko dane z dwóch pierwszych tabel: nazwy miejscowości "start" i "koniec".
Moje próby stworzenia takiego zapytania kończą się uzyskaniem nazwy tylko jednej miejscowości, a następną jest już numer id danego miasta.
Jak zrozumiem ideę, to mam nadzieje, ze dalej sobie poradzę.
Nie wiem, może źle zaprojektowałem bazę - jeśli ktoś byłby uprzejmy coś doradzić, będę wdzięczny.
Pozdrawiam..
ixpack
Tak na szybko:

moje tabele to: trasy (id_trasy, start, stop), miasta (id_miasta, miasto), przez(id_trasy, przez) - pozmieniaj nazwy i spróbuj zrozumieć wink.gif

trasa bezp:
  1. SELECT `alias1`.`miasto` AS `start_from`, `alias2`.`miasto` AS `end_at` FROM `trasy` LEFT JOIN `miasta` AS `alias1` ON `trasy`.`start`=`alias1`.`id_miasta` LEFT JOIN `miasta` AS `alias2` ON `trasy`.`stop`=`alias2`.`id_miasta` WHERE `id_trasy` = '1';


1 sposób z miastem przechodnim:
  1. SELECT `alias1`.`miasto` AS `start_from`, `alias2`.`miasto` AS `end_at`, (SELECT `miasto` FROM `przez` LEFT JOIN `miasta` ON `przez`.`przez`=`miasta`.`id_miasta` WHERE `id_trasy` = '1') FROM `trasy` LEFT JOIN `miasta` AS `alias1` ON `trasy`.`start`=`alias1`.`id_miasta` LEFT JOIN `miasta` AS `alias2` ON `trasy`.`stop`=`alias2`.`id_miasta` WHERE `id_trasy` = '1';


2 sposób z miastem przechodnim
  1. SELECT `alias1`.`miasto` AS `start_from`, `alias2`.`miasto` AS `end_at`, `alias3`.`miasto` AS `checkpoint` FROM `przez` LEFT JOIN `miasta` AS `alias3` ON `przez`.`przez`=`alias3`.`id_miasta`, `trasy` LEFT JOIN `miasta` AS `alias1` ON `trasy`.`start`=`alias1`.`id_miasta` LEFT JOIN `miasta` AS `alias2` ON `trasy`.`stop`=`alias2`.`id_miasta` WHERE `trasy`.`id_trasy` = '1' AND `przez`.`id_trasy` = '1';


A teraz takie moje przemyślenie na świeżo... Jeżeli masz wszędzie to miasto pośrednie, czy nie lepiej wstawić to do tabeli tras? wtedy masz 3 kolumny w jednym miejscu. No chyba, że są trasy bezpośrednie...
pozdr.

Ps. jak zerkniesz na 2-gi sposób z miastem przechodnim, nasuwa się myśl, że można zrobić trasy "alternatywne" wink.gif
pawelt
Super, wielkie dzięki za pomoc.
Dzięki tym przykładom dowiedziałem się, że można połączyć ze sobą kilka razy tą samą tabelę pod innym aliasem.

Tabelę PRZEZ stworzyłem między innymi dlatego, że istnieją bezpośrednie połączenia w których nie ma miejscowości pośrednich (dlatego, że są zbyt małe, a przebieg trasy na tych odcinkach jest oczywisty). Zastanawia mnie jednak fakt czy taki układ tabel jest dobry, jeśli będzie kilka miejscowości pośrednich na danej trasie, czy może coś trzeba zmienić?

Zależy mi na tym, żeby dobrze zbudować bazę, aby nie mieć problemów z tworzeniem zapytań w kodzie php.
ixpack
Wiesz, sam nie jestem ekspertem, ale zamiast wydzielać do osobnej tabeli dodałbym kolumnę "przez", gdzie np. 0 lub id startu oznaczałoby bezpośrednią trasę. Problemik pojawia się, gdy mamy więcej "miast przez" niż jedno. Wtedy nie możemy użyć tej kolumny, bo nie dodamy tam kilku id. Chyba, że będzie to np. varchar i dasz jakiś terminator pomiędzy id'kami i używając wyr. regularne podobnie podpinać nazwy etc. - robi się skomplikowane.
W tym momencie możesz dodać kilka miast przez i wydukać zapytanie, chyba będzie to optymalne - tzn. jak jest teraz. Pobaw się, zobacz... Tylko dla "przez" dodaj inny klucz główny, id_trasy może się przecież powtarzać. Wówczas baza zwróci wynik typu:
start, stop, przez1
start, stop, przez2
start, stop, przez3
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.