Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: problem z zapetlonym pytaniem
Forum PHP.pl > Forum > Bazy danych > MySQL
misty
hej, mam nastepujacy problem-mam sobie baze, pare tabel.. w nich informacje o osobach. kazda osoba moze miec mame lub(i) tate lub (i) wspolmalzonka. musze wyciagnac z bazy osoba ktora ma jak najwiecej wnukow. z tego co rozumiem (i jak to sobie wyobrazam) bedzie to osoba ktora ma wspolmalzonka i ktora jest ojcem/matka dla kogos, gdzie ten 'ktos' tez musi miec wspolmalzonka i byc dla kogos ojcem/matka.. strasznie to zapetlone. wrzucilam te dane do 3ch tablic:

  1. mysql> DESCRIBE osoba;
  2. +----------------+-------------+------+-----+---------+----------------+
  3. | FIELD | Type | NULL | KEY | DEFAULT | Extra |
  4. +----------------+-------------+------+-----+---------+----------------+
  5. | id_osoba | int(11) | NO | PRI | NULL | AUTO_INCREMENT |
  6. | imie | varchar(20) | NO | | | |
  7. | nazwisko | varchar(30) | NO | | | |
  8. | data_urodzenia | date | NO | | | |
  9. | plec | char(1) | NO | | | |
  10. | zarobki | varchar(15) | YES | | NULL | |
  11. +----------------+-------------+------+-----+---------+----------------+




  1. mysql> DESCRIBE rodzice;
  2. +-----------+---------+------+-----+---------+-------+
  3. | FIELD | Type | NULL | KEY | DEFAULT | Extra |
  4. +-----------+---------+------+-----+---------+-------+
  5. | id_osoba | int(11) | NO | | | |
  6. | id_matka | int(11) | YES | | NULL | |
  7. | id_ojciec | int(11) | YES | | NULL | |
  8. +-----------+---------+------+-----+---------+-------+



  1. mysql> DESCRIBE wspolmalzonek; +------------------+---------+------+-----+---------+-------+
  2. | FIELD | Type | NULL | KEY | DEFAULT | Extra |
  3. +------------------+---------+------+-----+---------+-------+
  4. | id_osoba | int(11) | NO | | | |
  5. | id_wspolmalzonek | int(11) | YES | | NULL | |
  6. +------------------+---------+------+-----+---------+-------+



no i nie moge wyciagnac tych danych.. tak sie zastanawiam-czy na pewno moge, czy dobrze zaprojektowalam tablice? czy moglby mi ktos pomoc w tym problemie?


pzdr,
misty
sowiq
Masz podstawowe błędy w założeniach.

Po pierwsze każde dziecko ma mamę i tatę (klonowanie jest na razie zabronione) -> do tabeli 'osoba' wrzuć pola id_matki, id_ojca (domyślnie np. -1 jeśli nieznany rodzic) .

Po drugie to, że ktoś ma dziecko wcale nie znaczy, że ma współmałżonka. Co w przypadku rozwodu i potomstwa z 2 różnych małżeństw? (rozwiązanie patrz wyżej).
Jeśli tak zrobisz, to wystarczy Ci jedno zapytanie z 2 JOIN'ami i po sprawie.

Tabela współmałżonek - dałbym tam id_os1, id_os2 (relacja w obie strony, przecież nie musisz pisać, że A jest współmałżonkiem B, a B współmałżonkiem A, bo to jasne). Do tego dorzuciłbym dwa pola - od, do (rozwód? śmierć?).
misty
hej,
przerobilam jak zasugerowales, tzn:

  1. mysql> DESCRIBE osoba;
  2. +----------------+-------------+------+-----+---------+----------------+
  3. | FIELD | Type | NULL | KEY | DEFAULT | Extra |
  4. +----------------+-------------+------+-----+---------+----------------+
  5. | id_osoba | int(11) | NO | PRI | NULL | AUTO_INCREMENT |
  6. | imie | varchar(20) | NO | | | |
  7. | nazwisko | varchar(30) | NO | | | |
  8. | data_urodzenia | date | NO | | | |
  9. | plec | char(1) | NO | | | |
  10. | id_matka | int(11) | YES | | NULL | |
  11. | id_ojciec | int(11) | YES | | NULL | |
  12. | zarobki | varchar(15) | YES | | NULL | |
  13. +----------------+-------------+------+-----+---------+----------------+


  1. mysql> DESCRIBE wspolmalzonek;
  2. +-------+---------+------+-----+---------+-------+
  3. | FIELD | Type | NULL | KEY | DEFAULT | Extra |
  4. +-------+---------+------+-----+---------+-------+
  5. | id_1 | int(11) | NO | | | |
  6. | id_2 | int(11) | NO | | | |
  7. +-------+---------+------+-----+---------+-------


no rozumiem ze teraz tabela "rodzice" nie jest potrzebna. kombinuje i nic mi nie wychodzi.. wpierw probuje znalezc osoby ktora sa matka lub ojcem:

  1. mysql> SELECT id_osoba FROM osoba WHERE id_osoba = id_matka OR id_osoba = id_ojciec;


i dostaje empty set.. oczywiscie wypelnilam tabele jakimis testowymi danymi.. od czego mam zaczac by to rozwiazac?


pzdr,
misty

aha, w zalozeniach jest ze dziecko jest z malzenstwa, tzn odrzucam przypadki ze malzenstwo moglo trwac np od-do i potem byc nastepne
sowiq
Cytat(misty @ 20.07.2009, 21:15:13 ) *
no rozumiem ze teraz tabela "rodzice" nie jest potrzebna.
Bardzo dobrze rozumujesz.

Zapytanie, które napisałaś mówi:
Cytat
Wybierz osoby, których (ID jest takie samo jak ID matki) LUB (ID jest takie samo jak ID ojca).
Pisałem Ci wcześniej, że klonowanie ludzi jest zakazane winksmiley.jpg

Zainteresuj się złączeniami. Spróbuj np. takie zapytanie wykonać:
Kod
SELECT o.imie, o.nazwisko, m.imie AS imie_matki, f.imie AS imie_ojca
    FROM osoba o
        LEFT JOIN osoba m ON (m.id_osoba = o.id_matka)
        LEFT JOIN osoba f ON (f.id_osoba = o.id_ojciec)

Wrzucam w tagi CODE, bo SQL ucinają wcięcia i kod jest mniej czytelny

ps. sorry, nie zajarzyłem od razu, że jesteś kobietą smile.gif

[edit]
@down,
poprawiłem kod
misty
nie za bardzo rozumiem to zapytanie wiec po prostu wrzucilam by zobaczyc jaki wynik dostane i wtedy przeanalizowac, ale dostalam blad:

  1. ERROR 1054 (42S22): Unknown COLUMN 'm.id' IN 'on clause'


jakoze nie bardzo rozumiem zapytanie to nie bardzo wiem jak poprawic..

dobra, tam powinno byc m.osoba_id, zaraz przeanalizuje
sowiq
Sorry za niedopatrzenie, ale myślałem, że takie błędy sama naprawisz smile.gif Kod poprawiony.

Poczytaj o JOIN'ach:
http://aylard.viawww.pl/2009/01/01/mysql-relacje/
http://dev.mysql.com/doc/refman/5.0/en/join.html
misty
no dobra, to zapytanie zwraca mi imiona rodzicow wszystkich osob. ale jaki to ma zwiazek z moim problemem? jak z tego wnukow wyciagnac?

tzn chyba tego "nie widze" po prostu. nie wiem co z czym zlozyc by wyszly wnuki. tzn ja rozumiem to tak, ze osoba o najwiekszej ilosci wnukow bedzie to osoba ktora jest matka lub ojcem i ktorej dziecko jest matka lub ojcem.. ale "nie widze" jak to zlaczyc
sowiq
Cytat(misty @ 20.07.2009, 21:39:25 ) *
[...]ale "nie widze" jak to zlaczyc
Po to podałem Ci linki - poczytaj. Jeśli to za mało, to Google -> MySQL JOIN. Znajdziesz wiele wyników zarówno po polsku jak i angielsku.

Zapytanie powinno wybrać wszystkie dzieci osoby o id = 123:
Kod
SELECT c.imie, c.nazwisko
    FROM osoby o
        LEFT JOIN osoby c ON (c.id_matka = o.id_osoby OR c.id_ojciec = o.id_osoby)
    WHERE o.id_osoby = 123
Żeby wybrać wnuki danej osoby, potrzebujesz małej modyfikacji tego zapytania. Wysil się trochę, bo nie dajemy gotowych rozwiązań. Nawet kobietom smile.gif
misty
no ale w sumie to zapytanie to jest praktycznie to co sama pisalam pare postow wyzej-czyli znajdz imiona, nazwiska (ja szukalam id) osob ktore sa matka albo ojcem, tyle ze ine dalam jeszcze "where". to mi zwraca empty set-nie wiem czemu. ej nie chodzi mi o zlaczenia, tylko o to ze ja nie potrafie sobie wyobrazic tego zapytania. zapetlam sie..
no bo -wybierz osoby ktore sa matka lub ojcem, przy czym ich dziecko tez jest matka lub ojcem.. no i z tego jeszcze maxa..



to Twoje zapytanie to to samo co:
  1. SELECT imie, nazwisko FROM osoba WHERE id_osoba = id_matka OR id_osoba = id_ojciec;

tyle ze bez 'where'. no ale jak mowilam-oba zwracaja empty set wiec cos jest nie tak

kurde, staram sie isc Twoim tokiem rozumowania i z tego co rozumiem to po where musza byc id ktora sa znow ojcami lub matkami, czyli robie kolejne zlaczenie:

  1. SELECT c.imie, c.nazwisko FROM osoba o LEFT JOIN osoba c ON (c.id_matka = o.id_osoba OR c.id_ojciec = o.id_osoba) WHERE o.id_osoba = (SELECT i.id_osoba FROM osoba i WHERE i.id_osoba = i.id_matka OR i.id_osoba = i.id_ojciec);


tyle ze to zwraca empty set, co jest w sumie logiczne skoro pierwsze wyrazenie zwraca juz empty set..
sowiq
Tak jak Ci napisałem wcześniej już, takie zapytanie:
  1. SELECT imie, nazwisko FROM osoba WHERE id_osoba = id_matka OR id_osoba = id_ojciec;
wybierze rekordy, które będą wyglądały np. tak:
Cytat
id_osoby = 15,
id_matka = 15,
id_ojciec = 23
, czyli spełniony będzie warunek, że id_osoby = id_matka ALBO id_osoby = id_ojciec. Porównujesz dwa pola tego samego rekordu.
Teraz rozumiesz swój tok myślenia?

A moje zapytanie:
Kod
SELECT c.imie, c.nazwisko
    FROM osoby o
        LEFT JOIN osoby c ON (c.id_matka = o.id_osoby OR c.id_ojciec = o.id_osoby)
    WHERE o.id_osoby = 123
mówi w skrócie: wybierz osoby, których matka lub ojciec mają id_osoby = 123. Można by to oczywiście napisać prościej, ale powyższe zapytanie używające JOIN'y możesz bardzo łatwo przerobić na wyszukiwanie wnuków, prawnuków itd.

Sorry, ale to są podstawy. Jeśli nie rozumiesz tego typu zapytań to pozostaje Ci tylko zajrzeć do manuala albo jakiegoś tutoriala.

Co do drugiej części pytania - wystarczą 3 rzeczy: GROUP BY, COUNT i MAX. Wszystko do znalezienia w manualu.
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-2019 Invision Power Services, Inc.