Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [HTML][MySQL][PHP]tabela w php, jeden do wielu? jak?
sindbad_zeglarz
post 22.06.2012, 09:23:05
Post #1





Grupa: Zarejestrowani
Postów: 29
Pomógł: 0
Dołączył: 18.04.2012

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


Hejka
Mam w bazie 3 tabele.
1 tabela - posiadłosci
2 tabela - dane userow
3 tabela - zlaczone id z tabela1 z id_tabela2 (jeden do wielu).

Chcialbym wyswietlić raporcik taki, aby w wyniku był następujący efekt.

Id tabela1 | id tabela 2 | imie tab2 | nazwisko tab 2
1 1 G P
tutaj nie chcę powtarzać tego samego id drugi raz tylko dać inne dane dane z id_tabeli2 , imie i nazwisko.


Przykład: DOM może mieć kilku właścicieli.
Ale jest to jeden DOM = jeden ID a kilka ID wlascicieli.

W SQL-u jakoś nie widzę żeby się to dało zrobić łatwo, chyba że ktoś coś podpowie.
A PHP jak to wyświetlić ?

Podpowiedzcie coś proszę.

Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 14)
Ruch Radzionków
post 22.06.2012, 09:27:14
Post #2





Grupa: Zarejestrowani
Postów: 311
Pomógł: 25
Dołączył: 29.08.2011

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


pobierasz z bazy dane za pomocą while a następnie w while pobierasz dane z innej tabeli nie wiem czy dokladnie o to ci chodzi


--------------------
Pomogłem daj pomógł
Go to the top of the page
+Quote Post
nospor
post 22.06.2012, 09:38:33
Post #3





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




@Ruch Radzionków totalnie nieoptymalne rozwiązanie.

@sindbad
Pobierasz jednym zapytaniem niezbędne dane. Z racji, że jeden dom moze miec wielu właścicieli, więc dane domu ci sie powtórzą - normalna sytuacja. Następnie w php grupujesz dane po domie, tam przechowujesz dane właścicieli a następne mając te dane robisz z nimi co ci się tylko podoba. Tutaj, pisałem o tym:
http://nospor.pl/grupowanie-wynikow.html


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
Shido
post 22.06.2012, 09:44:24
Post #4





Grupa: Zarejestrowani
Postów: 121
Pomógł: 22
Dołączył: 22.06.2012

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


Niby bawie się w w SQLu ale takich typowych relacji nie znalazłem.

Ale obeszlem to w taki sposób ( wykorzystam twój przykład z domem ):

Tabela dom:
ID, Nazwa, adres itp.

Tabela wlasciciele:
ID, Dom, imie, nazwisko itp.

i teraz na takiej zasadzie że w kolumnie Dom przy każdym z włascicieli widniej ID domu z tabei dom.

np:
1 | 3 | Jan | Kowalski
2 | 1 | Adam | Nowak
3 | 3 | Maurycy | Bąk

W takim wypadku robiąc raport z włascicieli domów pobierasz sobie z tabeli dom dane koniecznie ID i np. opcjionalnie inne kolumny

i po pobraniu każdego rekordu po ID domu ściągasz sobie z tabeli wlasciciele własicieli gdzie `dom` = '$id'

  1. $zapytanie = "SELECT * FROM `dom`;
  2. $wykonaj = mysql_query ($zapytanie);
  3. while($wiersz=mysql_fetch_array($wykonaj))
  4. {
  5. $id = $wiersz['ID'];
  6. $nazwa = $wiersz['nazwa'];
  7.  
  8. $zapytanie1 = "SELECT * FROM `wlasciciele` WHERE `dom` = '$id';
  9. $wykonaj1 = mysql_query ($zapytanie1);
  10. while($wiersz1=mysql_fetch_array($wykonaj1))
  11. {
  12. $imie = $wiersz1['imie'];
  13. $nazwisko = $wiersz1['nazwisko'];
  14. }
  15. }


Coś w ten deseń.

Można to też zrobic jednym zapytaniem rozległym SQL ale ja osobiście wolę porozbijać to na części i mieć wszystko przejżyste.

Ten post edytował Shido 22.06.2012, 09:46:10


--------------------
Sorka za błędy ort. jak coś dajcie znać na PW to popoprawiam.
Go to the top of the page
+Quote Post
nospor
post 22.06.2012, 09:50:29
Post #5





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
Można to też zrobic jednym zapytaniem rozległym SQL ale ja osobiście wolę porozbijać to na części i mieć wszystko przejżyste.
Może to i jest przejrzyste, ale niesamowicie mulaste.
W linku opisałem metodę, która jest o niebo szybsza i może jedynie ciut mniej przejrzysta na pierwszy rzut oka


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
sindbad_zeglarz
post 25.06.2012, 13:19:16
Post #6





Grupa: Zarejestrowani
Postów: 29
Pomógł: 0
Dołączył: 18.04.2012

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


ok a czy ksztalt zapytania ma znaczenie ?
Mam 3 tabele.
tab1 (dom)
id|nazwa|nrdomu
1|dom1|20
tab2 (wlasciciel)
id|imie|nazwisko|adres
tab3
id_dom|id_wlascisciel
1 | 1

lacze je w tej tabeli posredniej tab3.

Jak optymalnie napisac zapytanie?
(
  1. SELECT tab1.id, tab1.nazwa, tab1.nrdomu, tab2.id,tab2.imie,tab2.nazwisko,tab2.adres FROM tab1 tab1, tab2 tab2,tab3 tab3 WHERE tab3.id_dom=tab1.id ;
?

nospor jak to sie ma do Twojego skryptu ?
Bo chyba bym go uzył.
Go to the top of the page
+Quote Post
nospor
post 25.06.2012, 13:36:38
Post #7





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




WE from masz 3 tabele a łączysz tylko dwie. Takie zapytanie wypluje ci masę zbędnych powtórzen bez ładu i składu.

Cytat
nospor jak to sie ma do Twojego skryptu ?
Normalnie, tak jak opisałem w arcie.

Sorki ze tak skrótowo, ale zaraz musze leciec


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
sindbad_zeglarz
post 26.06.2012, 07:11:12
Post #8





Grupa: Zarejestrowani
Postów: 29
Pomógł: 0
Dołączył: 18.04.2012

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


to jak to napisac optymalnie ?
Go to the top of the page
+Quote Post
nospor
post 26.06.2012, 10:42:32
Post #9





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




No toć ci napisałem: skoro masz 3 tabele we FROM to masz je ze sobą połączyć a nie zostawiasz iloczyn kartezjański.

Najlepiej zrób left join
  1. SELECT * FROM tab1
  2. LEFT JOIN tab3 ON tab3.id_dom=tab1.id
  3. LEFT JOIN tab2 ON tab3.id_wlasciciel=tab2.id

To zapytanie zrowci ci dane z tabli dom wraz z przypisanymi do nich wlascicielami. Z racji, ze do jednego domu moze byc kilku wlascicieli, to rekordy domu będą się powtarzać. I w tym właśnie momemcie musisz to obrobić w php. A jak? Dokładnie to masz opisane w arcie co ci dałem do niego linka. Więc teraz wkońcu się z nim zapoznaj, bo jest to dam dokładnie wyjaśnione i podane na przykładzie.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
sindbad_zeglarz
post 27.06.2012, 13:04:02
Post #10





Grupa: Zarejestrowani
Postów: 29
Pomógł: 0
Dołączył: 18.04.2012

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


Zrobiłem tak dzieka za pomocną dłoń. Doczytałem o joinach, i zaczałem je kumać.

  1. SELECT * FROM dom d
  2. LEFT JOIN tab3 wmd ON wmd.id = d.id
  3. LEFT JOIN wlasciciel w ON wmd.id_wlasciciel = w.id


no i ładnie wyświetla ale oczywiscie powtarza id domu wszedzie tam gdzie jest wlasciciel (wlasciciel moze miec kilka domow).

zastosowanie skryptu kolegi NOSPOR fajnie by rozwiazało sprawę, ktos podpowie:
Jak to zastosować dla mojego przykładu ?

  1. <?php
  2. mysql_connect('localhost','root','') or die(mysql_error());
  3.  
  4. //pobranie wszystkich danych i ich pogrupowanie
  5. $sql = 'SELECT * FROM tabela1 dom
  6. LEFT JOIN tabela3 wmd ON wmd.dom_id = dom.id
  7. LEFT JOIN tabela2 w ON wmd.wlasciciel_id = w.id '; //sortujemy po nazwie kategorii
  8.  
  9. $res = mysql_query($sql) or die(mysql_error());
  10.  
  11. //najpierw pozyskamy niezbędne dane
  12. $wlasciciele = array();
  13. while ($row = mysql_fetch_array($res)){
  14. $cid = $row['id'];
  15.  
  16. //jeśli nie było jeszcze danego wlasciciela to go tworzymy
  17. if (!isset($wlasciciele[$cid]))
  18. $wlasciciele[$cid] = array('name' => $row['nazwisko'], 'wlasciciele' => array());
  19.  
  20. //dodajemy do kategorii kolejne produkty
  21. if (!empty($row['nazwisko'])) //jeśli istnieje produkt
  22. $wlasciciele[$cid]['wlasciciele'][] = array('name' => $row['nazwisko'], 'id'=>$row['id']);
  23. }
  24. print_r($wlasciciele); //do obejrzenia jak wygląda wygenerowana tablica
  25.  
  26. //a teraz wygenerujemy stronę na podstawie uzyskanych danych
  27. echo '<ul>';
  28. foreach ($wlasciciele as $idCat => $category){ //petla, która leci po kategoriach
  29. echo '<li>'.$category['name'].' (liczba wlasciciele: '.count($category['wlasciciele']).')<ul>';
  30. foreach ($category['wlasciciele'] as $nazwisko){ //pętla, która leci po produktach w kategorii
  31. echo '<li>wlasciciel o nazwie <b>'.$nazwisko['name'].'</b> i id <b>'.$nazwisko['id'].'</b></li>';
  32. }
  33. echo '</ul></li>';
  34. }
  35. echo '</ul>';


i jest problem,bo wyświetla
  1. wlasciciel o nazwie nowakowska i id 1
  2. wlasciciel o nazwie nowakowska i id 1
  3. wlasciciel o nazwie nowakowska i id 1
  4. wlasciciel o nazwie nowakowska i id 1
  5. wlasciciel o nazwie taranowska i id 1


już coś lepiej. ale zapętliłem się i nie wiem jak to ugryźć.
Coś nospor poradzisz ?


Ten post edytował sindbad_zeglarz 28.06.2012, 11:20:35
Go to the top of the page
+Quote Post
nospor
post 28.06.2012, 14:01:20
Post #11





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




1) Chciałeś grupować po domach więc grupuj w php po domach a nie po wlascicielach
2) $cid = $row['id']; tutaj bedziesz mial id z ostatniej tabeli a ciebie interesuje id domu.
wiec nie: select *
a: SELECT *, dom.id domid
i potem: $cid = $row['domid'];

Przyłoż się troszkę do tego a nie poszedłeś na zasadzie KOPIUJ WKLEJ


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
sindbad_zeglarz
post 29.06.2012, 10:54:05
Post #12





Grupa: Zarejestrowani
Postów: 29
Pomógł: 0
Dołączył: 18.04.2012

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


no niby dziala dziekuję Nospor, ale jeszcze nie tak jakbym chciał.
Zrobiłem tak.

SQL
  1. SELECT *,d.id domid,
  2. d.nr_domu numer,
  3. w.id wlaid,
  4. w.nazwisko nazwisko
  5. FROM dom d
  6. LEFT JOIN wlasciciel_ma_dom wmd ON wmd.dom_id = d.id
  7. LEFT JOIN wlasciciel w ON wmdz.wlasciciel_id = w.id
  8. LEFT JOIN gmina g ON d.gmina_id = g.id


Stworzenie tablicy:

  1. $domki = array();
  2. while ($row = mysql_fetch_array($res))
  3. {
  4. $domid = $row['domid'];
  5.  
  6. //jeśli nie było jeszcze danego domu to go tworzymy
  7. if (!isset($domy[$domid]))
  8. $dom[$domid] = array('nazwa' => $row['nr_domu'], 'nrdomu' => $row['numer'], 'dom' => array());
  9.  
  10. //dodajemy do do domu kolejnych wlascicieli
  11. if (!empty($row['nazwisko'])) //jeśli istnieje wlasciciel
  12. $dom[$domid]['wlasciciele'][] = array('wlasciciel' => $row['nazwisko'], 'id'=>$row['wlaid']);
  13. }
  14. print_r($dom);


pętla po tablicy:

  1. foreach ($dom as $domid => $iloscdomkow)
  2. {
  3. echo '<li><b>'.$iloscdomkow['nazwa'].'</b><br>';
  4. echo '<li>'.$iloscdomkow['nrdomu'].'<ul>';
  5. foreach ($iloscdomkow['wlasciciele'] as $allwlasc)
  6. {
  7. echo '<li>Nazwisko Właściciela '.$allwlasc['wlasciciel'].' - id '.$allwlasc['id'].'</li>';
  8. }
  9. echo '</ul></li>';
  10. }
  11. echo '</ul>';


Buduje/wynik:
Nazwisko Właściciela Nowak1 - id 2
135
135
Nazwisko Właściciela Nowak1 - id 2
134
134

i na końcu błąd:
Warning: Invalid argument supplied for foreach() line 78.
foreach ($iloscdomkow['wlasciciele'] as $allwlasc)

Nie wiem czy przez ten bład jest problem, ze powtarza nr domu.

Go to the top of the page
+Quote Post
nospor
post 29.06.2012, 11:14:08
Post #13





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




NIezły tu mamy burdel siostro....

Deklarujes tablice $domki = array(); ale potem używasz $dom a nie $domki
Deklarujesz w indekse 'dom' => array() ale potem uzywasz wlasciciele
Kod html to jakaś sieczka, np:
'<li><b>'.$iloscdomkow['nazwa'].'</b><br>';
LI panie kolego zamyka sie przy pomocy </LI> a nie BR

Wynik wyświetlania ma się nijak do kodu html i nawet nie próbuje go analizować bo mi włos na głowie staje wink.gif


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
sindbad_zeglarz
post 4.07.2012, 14:00:41
Post #14





Grupa: Zarejestrowani
Postów: 29
Pomógł: 0
Dołączył: 18.04.2012

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


hejka smile.gif Nospor pomocy smile.gif

zamieniłem domy z działkami smile.gif ale zasada taka sama. jedna dzialka wiele wlascicieli.

tablica:

  1. $dzialki = array();
  2. while ($wiersz = mysql_fetch_array($zapytanie))
  3. {
  4. $id = $wiersz['dzid'];
  5. echo $id.'.';
  6. if( !isset($dzialki[$id]) )
  7. {
  8. $dzialki[$id] = array(
  9. 'nr_dzialki' => $wiersz['nr_dzialki'],
  10. 'powierzchnia' => $wiersz['powierzchnia'],
  11. 'pow_w_pasie' => $wiersz['pow_w_pasie'],
  12. 'wlasciciele' => array(), // deklaracja jak nie ma zadnego wlasciciela
  13. 'dokumenty' => array() );
  14. }
  15.  
  16. if( !empty($wiersz['nazwisko'] ) )
  17. $dzialki[$id]['wlasciciele'][] = array( 'nazwisko' => $wiersz['nazwisko'] );
  18.  
  19. if( !empty($wiersz['nr_dokumentu'] ) )
  20. $dzialki[$id]['dokumenty'][] = array( 'nr_dokumentu' => $wiersz['nr_dokumentu'] );
  21. }


wyświetlenie tego: tutaj pojawia sie problem.
wyświetla co prawda jeden nr działki ale:
jeśli jest kilka dokumentów i do wlasciciela do jednej działki to tyle raze je dubluje ile jest dokumentów.

jesli jedna dzialka ma jednego wlasciciela - wyswietla ladnie
jesli jedna dzialka ma kilku wlascicieli to wyswietla ok.

---do tego momentu jest ok, ale jesli :
jesli jedna dzialka ma 2 wlascicieli i po 2 dokumenty sa do do wlasciciela to wyswietla zle.

przyklad:

nr dzialki| wlasciciel | dokument
10/1 | heniek 1 | dok1,dok2,dok3
------| heniek 2 | dok1,dok2,dok3
------| heniek 3 | dok1,dok2,dok3

  1. echo '<table border="1" aling=center>
  2. <td>Nr Dzialki</td>
  3. <td>Nazwisko</td>
  4. <td>Nr Dok</td>
  5. </tr>';
  6. foreach ($dzialki as $id => $dzialka)
  7. {
  8. echo '<tr><td>'.$dzialka['nr_dzialki'].'</td>';
  9. echo '<td>';
  10. foreach ( $dzialka['wlasciciele'] as $wlasciciel )
  11. {
  12. echo '<br />';
  13. echo $wlasciciel['nazwisko'].',';
  14. }
  15. echo '</td>';
  16. echo '<td>';
  17. foreach ( $dzialka['dokumenty'] as $dokument )
  18. {
  19. echo '<br />';
  20. echo $dokument['nr_dokumentu'].',';
  21. }
  22. echo '</td></tr>';
  23.  
  24. }
  25. echo '</table>';



Go to the top of the page
+Quote Post
nospor
post 10.07.2012, 09:13:42
Post #15





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




No ale pokaż zapytanie. Skad mam wiedziec co tam nacudowałes


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

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: 24.07.2025 - 22:54