Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][MYSQL] Złożone zapytanie SQL
Forum PHP.pl > Forum > Przedszkole
potreb
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?
dr_bonzo
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.
porady-it.pl
Łączyć możesz dowolną ilość tabel dodając kolejne JOIN-y 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.
potreb
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
phpion
No to trzaśnij zapytanie z dwoma JOINami łącząc tabele przy użyciu kluczy obcych. Nie bardzo rozumiem z czego robisz problem.
potreb
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. ?>
dr_bonzo
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
phpion
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?).
porady-it.pl
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 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
potreb
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ę.
porady-it.pl
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ę smile.gif
potreb
Na pewno ze skryptem tworzącym tablicę bo jak wyświetlam r['nazwisko'] wyświetla mi 3 pozycje.
nospor
  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 smile.gif

Cytat
Zastosowałem obsługę nospora
Nie, probowales zastosowac winksmiley.jpg
potreb
Oj próbowałem i dalej próbuje. Jak nadpisuje dane? Robię tym samym sposobem co w tutorialu.
nospor
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. ?>
potreb
Dobijasz mnie
nospor
pozytywnie czy negatywnie?
znaczy dziala czy nie?
potreb
Oczywiście że działa smile.gif Dzięki wielkie.
nospor
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 smile.gif
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-2025 Invision Power Services, Inc.