Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [PHP][MYSQL] Złożone zapytanie SQL
potreb
post
Post #1





Grupa: Zarejestrowani
Postów: 1 568
Pomógł: 192
Dołączył: 7.03.2005
Skąd: Warszawa

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


Witam mam opcję pobierania danych z dwóch tabel:
  1. <?php
  2. SELECT p.*, c.*  FROM pb_depart c LEFT JOIN pb_celldep p on p.id_dep = c.did WHERE p.id_dep = '$iddep' $csql $dssql ORDER BY c.kolejnosc ASC, p.idwysw ASC
  3. ?>


Chciałbym dodać jeszcze jedną tabele (pb_workers), której wartość np g.pr_id = p.cid czyli dla tabeli celldep.
Próbowałem to zrobić na zasadzie następnego left join, niestety nazwy z tabeli celldep wywalało mi tyle razi ile było przypisanych do niej rekordów z tabeli workers. Czy można połączyć 3 tabele?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 18)
dr_bonzo
post
Post #2





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

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


No to dobrze ci zrobilo, dla kazdego workers dodaje rekord z tym samym celldep dla ktorego worker sie odwoluje.
Nie wiem co chcesz osiagnac, ale musisz jakos (napisz slownie) ograniczyc jakie rekordy z workerow maja sie tu znajdowac.
Go to the top of the page
+Quote Post
porady-it.pl
post
Post #3





Grupa: Zarejestrowani
Postów: 89
Pomógł: 20
Dołączył: 13.05.2007
Skąd: Warszawa

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


Łączyć możesz dowolną ilość tabel dodając kolejne JOIN-y (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) Łatwiej było by gdybyś pokazał te trzy tabele i jak chcesz je połączyć ewentualnie co chcesz uzyskać było by łatwiej zbudować zapytanie.
Go to the top of the page
+Quote Post
potreb
post
Post #4





Grupa: Zarejestrowani
Postów: 1 568
Pomógł: 192
Dołączył: 7.03.2005
Skąd: Warszawa

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


No okez prosty opis. Mam 3 tabele
depart
did - id depart
name = nazwa

celldep
cid id celldep
name = nazwa
iddep - id depart

workers
id
nazwa
idcell

Pobieram id i nazwe depart nastepnie pobiera mi nazwe i id celldep dla depart i nastepnie z workersa pobiera mi dane dla celldepa. Czyli potrojne laczenie
kategorie -> podkategorie-> produkty
Probuje to zrobic na zasadzie jednego zapytania. Chce miec mozliwosc wyswietlenie danych dla jednego depart lub dla wielu
Go to the top of the page
+Quote Post
phpion
post
Post #5





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




No to trzaśnij zapytanie z dwoma JOINami łącząc tabele przy użyciu kluczy obcych. Nie bardzo rozumiem z czego robisz problem.
Go to the top of the page
+Quote Post
potreb
post
Post #6





Grupa: Zarejestrowani
Postów: 1 568
Pomógł: 192
Dołączył: 7.03.2005
Skąd: Warszawa

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


Zrobiłem takie zapytanie wcześniej, ale i tak nie działa poprawnie.
  1. <?php
  2. $sqldep = "SELECT p.*, c.*, g.*  FROM pb_depart c LEFT JOIN pb_celldep p on p.id_dep = c.did
  3. LEFT JOIN pb_workers p on p.cid = g.pr_idc WHERE p.id_dep = '$iddep' $csql $dssql ORDER BY c.kolejnosc ASC, p.idwysw ASC";
  4. ?>
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #7





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

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


U mnie dziala, i co mi zrobisz.

Pokaz dane, ile powiazanych rekordow ma kazdy z rekordow w drugiej tabeli, i pokaz co chcesz uzyskac.

PS. [OT] nazywal bys tabele/kolumny/aliasy bardziej czytelnie, konsekwentnie

np. masz depart zaliasowane do c
a celldep do p

nie prosciej depart => d, celldep => c ?
ja musialem sobie twoje zapytanie przepisac zeby co chwile nie sprawdzac co jest pod ktorym aliasem.

w kazdej tabeli dajesz id jako klucz glowny, klucze obce nazywasz po prostu depart_id, celldep_id
Ja to stosuje od dawna i
Go to the top of the page
+Quote Post
phpion
post
Post #8





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Cytat(dr_bonzo @ 22.04.2009, 21:58:55 ) *
w kazdej tabeli dajesz id jako klucz glowny, klucze obce nazywasz po prostu depart_id, celldep_id

Chyba najlepszy sposób. Klucz główny to u mnie zawsze pole id, a klucze obce to [nazwa_tabeli]_id. Dzięki temu mogę pisać zapytania "w ciemno" znajac tylko nazwy tabel i relacje między nimi.

A do problemu: możliwe, że sęk w tym, że masz zdublowane aliasy dla tabel. Już olać to, że są ponazywane zupełnie z kosmosu ale powtarzają się:
- pb_celldep p
- pb_workers p
Poza tym nie wiem co siedzi pod "$csql $dssql". Może tam jest błąd? Pokaż wygenerowane zapytanie, a nie to jak je tworzysz. Wklej wynik echo $sqldep i po sprawie.

PS: szkoda, że piszesz "nie działa poprawnie" zamiast wkleić błąd jaki otrzymujesz. Nie wiem jak przy dublowaniu aliasów ale tutaj "p.cid = g.pr_idc" na pewno otrzymujesz błąd (skąd się wzięło g?).

Ten post edytował phpion 23.04.2009, 08:37:38
Go to the top of the page
+Quote Post
porady-it.pl
post
Post #9





Grupa: Zarejestrowani
Postów: 89
Pomógł: 20
Dołączył: 13.05.2007
Skąd: Warszawa

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


Twoje zapytanie prawdopodobnie działa prawidłowo jednak możesz mieć problem z prawidłowym dostępem do elementów ze względu na użycie zapisu:

  1. ... p.*, c.*, g.* ...


Kolego przyjmij jakieś standardy zapisów nazw tabel i kluczy podstawowych oraz kluczy obcych w innym wypadku proste zapytanie jak to przysporzy Ci tylko problemów (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

  1. SELECT pd.name nazwa_depart, pc.name nazwa_celldep, pw.nazwa_workers
  2. FROM pb_depart pd
  3. LEFT JOIN pb_celldep pc ON pc.iddep = pd.did
  4. LEFT JOIN pb_workers pw ON pw.idcell = pc.cid
Go to the top of the page
+Quote Post
potreb
post
Post #10





Grupa: Zarejestrowani
Postów: 1 568
Pomógł: 192
Dołączył: 7.03.2005
Skąd: Warszawa

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


Dzięki za podpowiedzi. Zrobiłem tak aby było wszystko przejrzyste. Moje zapytanie wygląda teraz tak i kod php:
  1. <?php
  2. $sqldep = "SELECT d.*, c.*, w.* FROM pb_depart d
  3.    INNER JOIN pb_celldep c on c.id_depart = d.did
  4.    INNER JOIN pb_workers w on w.id_celldep = c.cid
  5.    WHERE c.id_depart = '$iddep' $csql $dssql ORDER BY w.nazwisko";
  6.    
  7.    $res = dbquery($sqldep);
  8.    $listar = array();
  9.    while ($r = dbarray($res))
  10.    {
  11.    
  12.        echo $r['nazwisko'];
  13.        $did = $r['did'];
  14.        $cid = $r['cid'];
  15.          if (!isset($listar[$did]))
  16.        $listar[$did] = array('name' => $r['name'], 'did' => $r['did'],'idept' => $r['iddept'],
  17.        'corder' => $r['order'], 'dshow' => $r['show'], 'wydzial' => array());
  18.  
  19.        if (!empty($r['namecell']))
  20.        $listar[$did]['wydzial'][$cid] = array('namecell' => $r['namecell'], 'cid' => $r['cid'], 'idwysw'=>$r['idwysw'],
  21.        'position'=> $r['position'], 'osoby'=> array());
  22.    
  23.        if (!empty($r['nazwisko']))
  24.        $listar[$did]['wydzial'][$cid]['osoby'][] = array('nazwisko' => $r['nazwisko']);
  25.    }
  26. ?>


Zapytanie działa poprawnie jednak nie potrafię rozbić tego dobrze. Zastosowałem obsługę nospora, do tworzenia tablicy.
W chwili obecnej wygląd to tak:
Kod
[26] => Array
        (
            [name] => Biuro Rachunkowe
            [did] => 26
            [idept] => BF
            [corder] => 1
            [dshow] => 0
            [wydzial] => Array
                (
                    [190] => Array
                        (
                            [namecell] => Kasa
                            [cid] => 190
                            [idwysw] => BAF IV
                            [position] => 0
                            [osoby] => Array
                                (
                                    [0] => Array
                                        (
                                            [nazwisko] => Dobosz
                                        )
                                )
                        )
                )
        )


Wszystko ładnie niby działa, jednak dla tablicy osoby występuje więcej nazwisk a wywala mi jedną. Nie wiem czy robię to w dobrej formie, ale inaczej tego nie widzę.
Go to the top of the page
+Quote Post
porady-it.pl
post
Post #11





Grupa: Zarejestrowani
Postów: 89
Pomógł: 20
Dołączył: 13.05.2007
Skąd: Warszawa

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


Zobacz w phpMyAdmin jaką listę rekordów zwróci zapytanie i będziesz wiedział czy jeszcze jest z nim coś nie tak czy może ze skryptem tworzącym tablicę (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
potreb
post
Post #12





Grupa: Zarejestrowani
Postów: 1 568
Pomógł: 192
Dołączył: 7.03.2005
Skąd: Warszawa

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


Na pewno ze skryptem tworzącym tablicę bo jak wyświetlam r['nazwisko'] wyświetla mi 3 pozycje.
Go to the top of the page
+Quote Post
nospor
post
Post #13





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




  1. <?php
  2. if (!empty($r['namecell']))
  3.       $listar[$did]['wydzial'][$cid] = array('namecell' => $r['namecell'], 'cid' => $r['cid'], 'idwysw'=>$r['idwysw'],
  4.       'position'=> $r['position'], 'osoby'=> array());
  5. ?>

Tym kodem nadpisujesz sobie za kazdym razem dane (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Cytat
Zastosowałem obsługę nospora
Nie, probowales zastosowac (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
Go to the top of the page
+Quote Post
potreb
post
Post #14





Grupa: Zarejestrowani
Postów: 1 568
Pomógł: 192
Dołączył: 7.03.2005
Skąd: Warszawa

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


Oj próbowałem i dalej próbuje. Jak nadpisuje dane? Robię tym samym sposobem co w tutorialu.
Go to the top of the page
+Quote Post
nospor
post
Post #15





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




Cytat
Robię tym samym sposobem co w tutorialu.
no wlasnie nie.

if (!empty($r['namecell'])) - przeciez to w kazdej iteracji bedzie prawdziwe, wiec za kazdym razem to nadpiszesz. sprobuj tak:
  1. <?php
  2. if (!isset($listar[$did]['wydzial'][$cid]))
  3.       $listar[$did]['wydzial'][$cid] = array('namecell' => $r['namecell'], 'cid' => $r['cid'], 'idwysw'=>$r['idwysw'],
  4.       'position'=> $r['position'], 'osoby'=> array());
  5. ?>
Go to the top of the page
+Quote Post
potreb
post
Post #16





Grupa: Zarejestrowani
Postów: 1 568
Pomógł: 192
Dołączył: 7.03.2005
Skąd: Warszawa

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


Dobijasz mnie
Go to the top of the page
+Quote Post
nospor
post
Post #17





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




pozytywnie czy negatywnie?
znaczy dziala czy nie?
Go to the top of the page
+Quote Post
potreb
post
Post #18





Grupa: Zarejestrowani
Postów: 1 568
Pomógł: 192
Dołączył: 7.03.2005
Skąd: Warszawa

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


Oczywiście że działa (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Dzięki wielkie.
Go to the top of the page
+Quote Post
nospor
post
Post #19





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




Pisales ze robiles wg. mojego tutka a ja napisalem ze nie do konca. W sumie to pisales wg. mojego tutka tylko nie zwrociles uwagi na maly szczegół:
tutek opisywany byl na przykladzie tablicy dwuwymiarowej. tutaj zaś miales tablice 3-wymiarową i niestety tego nie uwzględniles. Traktowales drugi poziom tablicy tak jak drugi poziom tablicy z tutka co bylo oczywiscie błedem. Ten drugi poziom mialbyc rowniez traktowany jako pierwszy, gdyz nie byl ostatnim.

Ot takie male podsumowanie tematu (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 22.08.2025 - 15:15