Z Poszerzeniem prostego przykładu dałem sobie rade ale w praktyce się kiełbasi
Teraz analogicznie chcę połączyć te 4 tabele polami id, kraj, region, miasto, punkt i pobrać pola nazwa , z tym że:
-tabela kraj jest nadrzędna.
-pole kraj tabeli region = polu id tabeli kraj
-pole kraj tabeli miasto = polu kraj tabeli region
-pole region tabeli miasto = polu id tabeli region
-pole kraj tabeli punkt = polu kraj tabeli miasto
-pole region tabeli punkt = polu region tabeli miasto
-pole miasto tabeli punkt = polu id tabeli miasto
o ile mi się nic nie pokićkało
Jak to połączyć?
Złączono Posta: 14.08.2007 (Wto) 2:12
udało mi się połączyć
Ale są dwa problemy.
-jak dodam jeszcze wyszukiwanie
to się wykrzacza
-jeżeli dany rekord ma braki to się krzaczy
konkretnie region , nie jest on obowiązkowy i gdy w danym kraju nie mam podziału na regiony, w tabelach miasto i punkt pole region=0 - a t nie ma odpowiednika w tabelach kraj i region
pewnie IF należy użyć albo coś innego ale jak?
Złączono Posta: 14.08.2007 (Wto) 2:26
kombinowałem tak
Ale nie pokazuje dalej wszystkich punktów. Nie pokazuje tych gdzie w tabeli punkt i miasto pole region=0.
Dla wyjaśnienia, numeracja pól id wszędzie zaczyna się od 1
Pole region masz INT NOT NULL, zmień je tak, aby można było umieścić wartość NULL. Jeśli region nie jest wymagany, “insertuj” mu właśnie NULL. Potem przy pobieraniu sprawdzaj czy pole region nie jest puste. I w zależności zrób odpowiednie warunki. Jeśli nie jest puste postępuj normalnie, a jeśli nie, przerób warunek aby nie zwracał uwagi na region.
pola region zmieniłem na NULL i tak też dodaję do bazy.
Problem jednak pozostaje
Ale może bardziej obrazowo,
zgaduje że problem pojawia się na lini tego przypisania:
pole region tabeli miasto = polu id tabeli region
czyli w zapytaniu: miasto.region=region.id (a to ciągnie za sobą kolejne zwalone przypisanie punkt.region=miasto.region )- bo punkt.region i miasto.region mogą mieć wartość NULL , a to nie ma wówczas odzwierciedlenia w region.id będącym NOT NULL i dodatkowo prumary key
Dlatego post wcześniej kombinowałem z IF w zapytaniu ale to mi nie chce działać, bo zwraca i tak tylko rekordy gdzie region <> NULL
Jak poprawić to zapytanie by zwracało również rekordy gdzie w tabelach miasto i punkt , pole region ma wartość NULL ??
Hmmm… a może nie tu drogi szukamy. Spróbuj w ten sposób:
where ... AND (miasto.region=NULL OR (miasto.region=region.id))
wyrażenie połączone operatorem logicznym LUB (OR) będzie miało wartość TRUE jeśli przynajmniej jedno z podwyrażeń będzie TRUE. Dlatego powinno zwrócić wszystko…
Więc jeśli się nie pomyliłem powinno wyglądać tak:
"SELECT punkt.id AS pid, punkt.nazwa AS nazwa_p, miasto.nazwa AS nazwa_m, region.nazwa AS nazwa_r, kraj.nazwa AS nazwa_k FROM punkt, miasto, region, kraj WHERE (region.kraj=kraj.id AND miasto.kraj=region.kraj AND (miasto.region=NULL OR (miasto.region=region.id)) AND punkt.kraj=miasto.kraj AND (punkt.region=NULL OR (punkt.region=miasto.region)) AND punkt.miasto=miasto.id)"
Przed chwilą sprawdziłem czy z tym NULL się nie przejechałem… i kurczę… hehe, chyba tak. Chodzi o to, że (przynajmniej mi) po warunku z NULL nic nie zwróciło. Więc może zamiast:
Więc tak, w ten sposób, jaki chcesz nie da się pobrać raczej. Po prostu jeśli dane pole jest NULL, to nie ma dla niego relacji. Jeśli jego wartość nie istnieje to nie można go porównać z innym polem.
Są 2 wyjścia, jedno bardziej wydajne i lepsze, drugie zdecydowanie gorsze.
w tabeli region ustawiasz jeden rekord, gdzie w “kraj” będzie miał jakąś niepowtarzalną wartość (np. 0 - zero) a w “nazwa” nie będzie miał nic. Następnie w tabeli miasto w polu “region” będzie miał właśnie to zero. Wtedy relacja zadziała w 100%.
Pobierasz wszystko i w PHP filtrujesz, ale w ten sposób jeśli będziesz miał dużo danych w bazie, możesz zabić serwer.
odpada a 1. - już cos podobnie kombinowałem tu jednak pojawia się kłopot bo jak w regionie zrobię rekord bez nazwy z polem kraj=0, to relacja w dół może i będzie ale nie powiąże rekord.kraj=kraj.id
Już myślę żeby rozdzielić wyszukiwanie selectem oddzielnie na kraj, region, miasto, punkt - to częściowo rozwiąze problem
Kombinuje może strasznie ale wywaliłem region - całą tebele region i pola region z pozostałych 3tabel.
Czy dla samych tabel kraj, miasto, punkt da rady zrobić zapytanie by zwracało wszystkie rekordy gdzie relacja kraj>miasto>punkt i kraj>miasto (brak zdefiniowanych punktów)??
czyli wszystkie punkty+miasta bez zdefiniowanych punktów
Jeżeli jakieś rekordy mają swoje punkty, a inne nie, to tak samo jak w przypadku regionu, relacja nie zadziała. Więc najlepszym rozwiązaniem byłoby po prostu danie obowiązkowych punktów.
A właściwie to co chcesz przechowywać w tabeli punkt? Bo jak tak patrzę na strukturę Twojej bazy, to tak się zastanawiam czy nie można by jej uprościć
Właśnie nie tylko punkty, a szkoda bo by jedna tabelka wtedy starczyłą.
wporzo, podzieliłem sobie i wyszukuję rekordów w wybranej tabeli po słowach kluczowych w 2 polach.
Mam taki kod
I działa, ale za dobrze. Bo potworzyłem sobie dodatkowo w każdej tabeli rekord o nazwie test i ze słowem test w polu url i teraz w wyszukiwaniu po kraju jest spox - tylko jedna tabela.
Ale kłopot pojawia się w pozostałych, bo tam dołączone są tabele miasto i kraj. No i w nich jak by wyszukiwało nie tylko po polach punkt.url, punkt.nazwa i miasto.url, miasto.nazwa, gdzie dzięki relacjom miał bym niezbędne dane z nadrzędnych tabel ale jak by szukało po polach url i nazwa we wszystkich dołączonych tabelach bo wyniki mam 2 dla miasta (miasto+kraj) i 3 dla punktu (punkt+miasto+kraj)