Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> problem z zapetlonym pytaniem
misty
post 20.07.2009, 14:22:32
Post #1





Grupa: Zarejestrowani
Postów: 366
Pomógł: 0
Dołączył: 2.01.2007

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


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

Ten post edytował misty 20.07.2009, 14:23:20
Go to the top of the page
+Quote Post
sowiq
post 20.07.2009, 14:29:36
Post #2





Grupa: Zarejestrowani
Postów: 1 890
Pomógł: 339
Dołączył: 14.12.2006
Skąd: Warszawa

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


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ć?).

Ten post edytował sowiq 20.07.2009, 14:30:06
Go to the top of the page
+Quote Post
misty
post 20.07.2009, 20:23:06
Post #3





Grupa: Zarejestrowani
Postów: 366
Pomógł: 0
Dołączył: 2.01.2007

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


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
Go to the top of the page
+Quote Post
sowiq
post 20.07.2009, 20:26:39
Post #4





Grupa: Zarejestrowani
Postów: 1 890
Pomógł: 339
Dołączył: 14.12.2006
Skąd: Warszawa

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


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

Ten post edytował sowiq 20.07.2009, 20:34:40
Go to the top of the page
+Quote Post
misty
post 20.07.2009, 20:36:05
Post #5





Grupa: Zarejestrowani
Postów: 366
Pomógł: 0
Dołączył: 2.01.2007

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


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
Go to the top of the page
+Quote Post
sowiq
post 20.07.2009, 20:37:04
Post #6





Grupa: Zarejestrowani
Postów: 1 890
Pomógł: 339
Dołączył: 14.12.2006
Skąd: Warszawa

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


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
Go to the top of the page
+Quote Post
misty
post 20.07.2009, 20:39:25
Post #7





Grupa: Zarejestrowani
Postów: 366
Pomógł: 0
Dołączył: 2.01.2007

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


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
Go to the top of the page
+Quote Post
sowiq
post 20.07.2009, 21:06:21
Post #8





Grupa: Zarejestrowani
Postów: 1 890
Pomógł: 339
Dołączył: 14.12.2006
Skąd: Warszawa

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


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

Ten post edytował sowiq 20.07.2009, 21:09:20
Go to the top of the page
+Quote Post
misty
post 20.07.2009, 21:37:56
Post #9





Grupa: Zarejestrowani
Postów: 366
Pomógł: 0
Dołączył: 2.01.2007

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


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..
Go to the top of the page
+Quote Post
sowiq
post 20.07.2009, 22:00:34
Post #10





Grupa: Zarejestrowani
Postów: 1 890
Pomógł: 339
Dołączył: 14.12.2006
Skąd: Warszawa

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


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.

Ten post edytował sowiq 20.07.2009, 22:03:26
Go to the top of the page
+Quote Post

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

 



RSS Wersja Lo-Fi Aktualny czas: 29.03.2024 - 08:22