Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Relacje między tabelami
Forum PHP.pl > Forum > Przedszkole
casperii
zachodzę sobie w głowę jak powinno wyglądać dobrze napisane zapytanie do mysqla:
Są dwie tabele w których jest to samo ID, chce wyświetlić wszystkie rekordy , ale jeśli w drugiej tabeli jest to samo ID wyświetli się coś extra (np podświetlę , pogrubie sobie etc).

  1. SELECT * FROM tabela1, tabela 2 WHERE tabela1.id = tabela2.id


wyświetli nam tylko te gdzie relacja pomiędzy niby jest spójna.
Natural Join też odpada.

Dla samego połączenia tabel wystarczy:
  1. SELECT * FROM tabela1, tabela 2


a jak bym chciał w miejsce gwiazdki zrobić alias As podswietlenie ?

Czyżby tak:
  1. SELECT `tabela1`.`id` =`tabela2`.`id` AS `podswietlenie` FROM tabela1, tabela 2

nospor
LEFT JOIN
casperii
No dobra ale jest jedno ale:
  1. SELECT * FROM `tabela1` LEFT JOIN `tabela2` ON `tabela1`.`pid` = `tabela2`.`aid`


Jeżeli mam w tabeli2 2 x wartość tą samą aid którą porównuje sobie z tabela 1 to mi się nazwy z tabeli1 dublują , jak to ugryźć group by aid ?

tabela1:
id, produkt

1 | Auto

tabela2:
id, adres, rodzaj

1 | www | B
1 | ww2 | C

i dla rekordu ID 1 powinno mi pokazać Auto <a href="www">B</a> <a href="ww2">C</a>



jak zrobię tak:
  1. SELECT * FROM `tabela1` LEFT JOIN `tabela2` ON `tabela`.`id` = `tabela2.`.`id` GROUP BY `tabela1`.`id`


to wyświetli mi Auto B , chociaż jest jeszcze C

jak zrobię tak:
  1. SELECT * FROM `tabela1` LEFT JOIN `tabela2` ON `tabela`.`id` = `tabela2.`.`id`


to wyświetli mi
Auto B
Auto C

a moim założeniem jest wyświetlenie Auto B C
nospor
Jesli uzywasz grupowania i chcesz w select pobrac zagregowane dane, to wypadaloby uzyc jakiejs funkcji do tego, w zaleznosci od potrzeb. W twoim przypadku masz uzyc GROUP_CONCAT
casperii
@nospor :

  1. SELECT *, `id`, GROUP_CONCAT(`id`) FROM `tabela1`
  2. LEFT JOIN `tabela2` ON `tabela1`.`id` = `tabela2`.`id`


powyższe pokaże mi Auto, A, C - jest idealnie, ale jest problem jeśli w bazie są jeszcze inne , ponieważ pobiera mi tylko 1 rekord.

1 | Auto
2 | Rower

tabela2:
id, adres, rodzaj

1 | www | B
1 | ww2 | C
2 | ww2 | Z
2 | ww2 | T
nospor
Zjadles GROUP BY... skup sie troche
casperii
@nospor ok , racja:

  1. SELECT *, `id`, GROUP_CONCAT(`id`) FROM `tabela1`
  2. LEFT JOIN `tabela2` ON `tabela1`.`id` = `tabela2`.`id` GROUP BY `id`



powyższe pokaże mi
Auto, A, C
Rower Z, T

A co jeśli w bazie miałbym tak:

1 | Auto
2 | Rower
3 | Samolot

tabela2:
id, adres, rodzaj

1 | www | B
1 | ww2 | C
2 | ww2 | Z
2 | ww2 | T

i chciałbym też wyświetlić, samolot chociaż nie ma powiązania w tabeli 2 ?
Pyton_000
Zamiast pytać o głupooty to byś to lepiej sprawdził.
casperii
@Pyton_000 gdyby to działało to bym nie pytał tutaj :-)
Jeszcze raz napiszę co chcę osiągnąć:

tabela1:
id, produkt

1 | Auto
2 | Rower
3 | Samolot

tabela2:
id, adres, rodzaj

1 | www | B
1 | ww2 | C
2 | ww2 | Z
2 | ww2 | T


powinno mi wyświetlić:
Auto B, C
Rower Z, T
Samolot
bostaf
Cytat(casperii @ 13.06.2017, 19:55:37 ) *
@nospor ok , racja:

  1. SELECT *, `id`, GROUP_CONCAT(`id`) FROM `tabela1`
  2. LEFT JOIN `tabela2` ON `tabela1`.`id` = `tabela2`.`id` GROUP BY `id`



powyższe pokaże mi
Auto, A, C
Rower Z, T
.
.
.
i chciałbym też wyświetlić, samolot chociaż nie ma powiązania w tabeli 2 ?

Ja to bym się spodziewał po wywołaniu tego zapytania błędu "Column 'id' in field list is ambiguous". Chyba masz jakieś specyficzne ustawienie środowiska, które ukrywa te błędy, skoro Ci w ogóle to zapytanie coś zwraca.
@Pyton, nospor - dlaczego to zapytanie w ogóle działa?

Ani SELECT ani GROUP BY w tym zapytaniu nie wiedzą po którym id mają grupować. U ciebie tak jakby domyślnie grupuje po ostatnim, czyli pomija ID z pierwszej tabeli. Daj GROUP BY tabela1.id i będzie hulało.
W select'cie też sprecyzuj, o który id chodzi (tabela1 czy tabela2).
casperii
@bostaf jeśli nie zauważyłeś to są przykładowe tabele by zrozumieć. By zobrazować lepiej nazwę tabele

product:
pid, name

1 | Auto
2 | Rower
3 | Samolot

Category:
aid, adres, cat

1 | www | B
1 | ww2 | C
2 | ww2 | Z
2 | ww2 | T

  1. SELECT *, GROUP_CONCAT(`aid`) FROM `Category` LEFT JOIN `product` ON `Category`.`aid` = `product`.`pid` GROUP BY `Category`.`aid`


powyższe zwraca mi tylko:
Auto, A, C
Rower Z, T

a Samolot gdzie się pytam ? smile.gif
trueblue
Podane przez Ciebie zapytanie na pewno nie zwróci Ci tego wyniku. Robisz GROUP_CONCAT na aid, jak również GROUP BY na aid, dodatkowo łączysz odwrotnie tabele. Pomieszanie z poplątaniem.

  1. SELECT p.name, GROUP_CONCAT(c.cat) FROM product AS p LEFT JOIN category AS c ON c.aid = p.pid GROUP BY p.pid
bostaf
Cytat(casperii @ 14.06.2017, 21:49:58 ) *
@bostaf jeśli nie zauważyłeś to są przykładowe tabele by zrozumieć. By zobrazować lepiej nazwę tabele

Nie zauważyłem rzeczywiście smile.gif Ale odpowiedź jest ta sama - grupuj po id z pierwszej tabeli. I wybieraj konkretne pola w select, zamiast wszystkich, czyli nie *, a
  1. SELECT concat_ws(' ', product.name, group_concat(Category.cat separator ', '))
rufuspl
Cześć.
Nie zakładam nowego wątku, bo wygląda mi na to, że moje pytanie jest pokrewne do tematu tego wątku.
Robię aplikację webową do pracy, w której w tabeli "pacjent" jako klucze obce używam dwa razy id z innej tabeli - "personel" (jest to 2x id lekarza z tabelki "personel", bo jeden lekarz kieruje pacjenta a drugi go kwalifikuje). Na liście zabiegów mają pojawić się zamiast id lekarzy ich nazwiska. Jak zrobić SELECT, aby uzyskać nazwiska tych dwóch lekarzy?

  1. Struktura tabeli dla tabeli `pacjent`
  2. --
  3.  
  4. CREATE TABLE IF NOT EXISTS `pacjent` (
  5. `id_pac` int(5) NOT NULL AUTO_INCREMENT,
  6. `pac_nazwisko` varchar(50) COLLATE utf8_polish_ci NOT NULL,
  7. `pac_imie` varchar(20) COLLATE utf8_polish_ci NOT NULL,
  8. `id_plec` int(1) NOT NULL,
  9. `data_ur` date NOT NULL,
  10. `pesel` varchar(11) COLLATE utf8_polish_ci NOT NULL,
  11. `ks_gl_nr` int(3) NOT NULL,
  12. `ks_gl_rok` int(4) NOT NULL,
  13. `id_dok` char(1) COLLATE utf8_polish_ci NOT NULL,
  14. `dok_toz_nr` char(20) COLLATE utf8_polish_ci NOT NULL,
  15. `data_zab` date NOT NULL,
  16. `id_tryb_lecz` int(1) NOT NULL,
  17. `id_jos_kier` int(2) NOT NULL,
  18. `id_personel_lek_kier` int(2) NOT NULL,
  19. `id_personel_lek_kwal` int(2) NOT NULL,
  20. `id_icd9` int(5) NOT NULL,
  21. `opis_dod` text COLLATE utf8_polish_ci NOT NULL,
  22. `uwagi` text COLLATE utf8_polish_ci NOT NULL,
  23. `id_status` int(1) NOT NULL,
  24. PRIMARY KEY (`id_pac`),
  25. KEY `id_plec` (`id_plec`),
  26. KEY `id_dok` (`id_dok`),
  27. KEY `id_rodz_lecz` (`id_tryb_lecz`),
  28. KEY `id_jos_kier` (`id_jos_kier`),
  29. KEY `id_lek_kier` (`id_personel_lek_kier`),
  30. KEY `id_icd9` (`id_icd9`),
  31. KEY `id_status` (`id_status`)
  32. )


  1. Struktura tabeli dla tabeli `personel`
  2. --
  3.  
  4. CREATE TABLE IF NOT EXISTS `personel` (
  5. `id_personel` int(2) NOT NULL AUTO_INCREMENT,
  6. `per_imie` char(20) COLLATE utf8_polish_ci NOT NULL,
  7. `per_nazwisko` char(50) COLLATE utf8_polish_ci NOT NULL,
  8. `nr_prawa` char(10) COLLATE utf8_polish_ci NOT NULL,
  9. `id_jos_kier` int(2) NOT NULL,
  10. `id_personel_typ` int(1) NOT NULL,
  11. PRIMARY KEY (`id_personel`),
  12. KEY `id_jos_kier` (`id_jos_kier`),
  13. KEY `id_jos_kier_2` (`id_jos_kier`),
  14. KEY `id_grupyz` (`id_personel_typ`)
  15. )


Na tą chwilę używam inner/left join i odpowiednie klucze obce ale w ten sposób potrafię wyciągnąć tylko jednego lekarza.
Pyton_000
bo masz użyć 2x left join.

rufuspl
Cytat(Pyton_000 @ 17.06.2017, 14:24:22 ) *
bo masz użyć 2x left join.


OK. Ale jak później wyświetlić wynik zapytania i te dwa nazwiska

  1. while($pole=mysqli_fetch_assoc($zapytanie)){
  2. echo '<tr><td>';
  3. echo '</td>';
  4. echo '<td>'.$pole['id_pac'].'</td>';
  5. echo '<td>'.$pole['pac_nazwisko'].' '.$pole['pac_imie'].'</td>';
  6. echo '<td>'.$pole['pesel'].'</td>';
  7. echo '<td>'.$pole['ks_gl_nr'].' / '.$pole['ks_gl_rok'].'</td>';
  8. echo '<td>'.$pole['jos_skrot'].'</td>';
  9. echo '<td>'.$pole['data_zab'].'</td>';
  10. echo '<td>'.$pole['stat_nazwa'].'</td>';
  11. echo '<td>'.$pole['tryb_nazwa'].'</td>';
  12. echo '<td>'.$pole['id_icd9'].'</td>';
  13. /* echo '<td>'.$pole['per_nazwisko'].'</td>'; */
  14. }


Wykomentowałem w kodzie linijkę odpowiedzialną za wyświetlenie jednego nazwiska. Jak je rozróżnić i wyświetlić drugie nazwisko?
Pyton_000
dodajesz aliasy w zapytaniu w SELECT dla nazwisk
rufuspl
Cytat(Pyton_000 @ 17.06.2017, 15:39:55 ) *
dodajesz aliasy w zapytaniu w SELECT dla nazwisk


Nie bardzo wiem jak a i szukanie rozwiązania nie przyniosło oczekiwanych skutków sad.gif

Mam na tą chwilę coś takiego

  1. <?php
  2. include('connect.inc');
  3. $id=$_GET['id'];
  4. mysqli_set_charset($db_lnk, "utf8");
  5. $zapytanie=mysqli_query($db_lnk, "SELECT
  6. pacjent.id_pac,
  7. pacjent.pac_nazwisko,
  8. pacjent.pac_imie,
  9. pacjent.pesel,
  10. pacjent.ks_gl_nr,
  11. pacjent.ks_gl_rok,
  12. pacjent.data_zab,
  13. sl_jos_kier.id_jos_kier,
  14. sl_jos_kier.jos_nazwa,
  15. sl_status.id_status,
  16. sl_status.stat_nazwa,
  17. sl_tryb_lecz.id_tryb_lecz,
  18. sl_tryb_lecz.tryb_nazwa,
  19. sl_icd9.id_icd9,
  20. sl_icd9.icd9_kod,
  21. personel.id_personel,
  22. personel.per_imie,
  23. personel.per_nazwisko
  24. from pacjent left join sl_jos_kier using (id_jos_kier)
  25. left join sl_status using (id_status)
  26. left join sl_tryb_lecz using (id_tryb_lecz)
  27. left join sl_icd9 using (id_icd9)
  28. left join personel on pacjent.id_personel_lek_kier=personel.id_personel
  29. where pacjent.id_pac=$id");
  30. while($pole=mysqli_fetch_assoc($zapytanie)){
  31.  
  32. /* przyciski */
  33. echo "<form><input class=\"button\" type=\"button\" value=\"Anestezjolog\" onclick=\"window.location.href='znieczulenie.php?id=$pole[id_pac]'\">";
  34. echo "<input class=\"button\" type=\"button\" value=\"Operator\" onclick=\"window.location.href='opis.php?id=$pole[id_pac]'\">";
  35. echo "<input class=\"button\" type=\"button\" value=\"Zespół operacyjny\" onclick=\"window.location.href='zespol.php?id=$pole[id_pac]'\">";
  36. echo "<input class=\"button\" type=\"button\" value=\"WYDRUK\" onclick=\"window.print()\"></form>";
  37. /* --------- */
  38. echo '<table id=\"zab\" border=\"1\"><tbody>';
  39. echo '<tr>';
  40. echo '<td>Nr zabiegu:</td><td width=\"200px\">'.$pole['id_pac'].'</td>';
  41. echo '</tr><tr>';
  42. echo '<td>Nr Ks. Gł.:</td><td>'.$pole['ks_gl_nr'].' / '.$pole['ks_gl_rok'].'</td>';
  43. echo '</tr><tr>';
  44. echo '<td>Pacjent:</td><td>'.$pole['pac_imie'].' '.$pole['pac_nazwisko'].'</td>';
  45. echo '</tr><tr>';
  46. echo '<td>PESEL:</td><td>'.$pole['pesel'].'</td>';
  47. echo '</tr>';
  48. echo '</tr><tr>';
  49. echo '<td>Data zabiegu:</td><td>'.$pole['data_zab'].'</td>';
  50. echo '</tr>';
  51. echo '</tr><tr>';
  52. echo '<td>Rodzaj leczenia:</td><td>'.$pole['tryb_nazwa'].'</td>';
  53. echo '</tr>';
  54. echo '</tr><tr>';
  55. echo '<td>Jednostka kier.:</td><td>'.$pole['jos_nazwa'].'</td>';
  56. echo '</tr>';
  57. echo '</tr><tr>';
  58. echo '<td>Lekarz kier.: </td><td>'.$pole['per_imie'].' '.$pole['per_nazwisko'].'</td>';
  59. echo '</tr><tr>';
  60. echo '<td>Lekarz kwal.:</td><td> TUTAJ POTRZEBUJĘ IMIĘ I NAZWISKO LEK. KWALIFIKUJĄCEGO </td>';
  61. echo '</tr><tr>';
  62. echo '<td>Status:</td><td>'.$pole['stat_nazwa'].'</td>';
  63. echo '</tr>';
  64. echo '</tbody></table>';
  65. }
  66. ?>


Możesz mi pokazać jak na moim kodzie lub na jakimś innym przykładzie?
Pyton_000
Kod
SELECT tabel1.id AS ID_1, tabela2.id AS ID_2
rufuspl
Cytat(Pyton_000 @ 18.06.2017, 09:29:11 ) *
Kod
SELECT tabel1.id AS ID_1, tabela2.id AS ID_2


Tyle, że ja w tabeli1 (pacjent) mam klucz (id) z tabeli2 (personel) a na stronie ma pojawić się nazwisko i imię pobrane z tabeli2 (personel) odszukane po id.
I nie bardzo wiem, jak to zrobić dla drugiego lekarza, czyli jak użyć aliasu we fragmencie

  1. echo '<td>Lekarz kier.: </td><td>'.$pole['per_imie'].' '.$pole['per_nazwisko'].'</td>';
Pyton_000
Wyraźnie napisałem że masz zrobić 2x left join do personel za każdym razem nadając mu inny alias, i w select potem sobie wyciągasz po tych aliasach.
rufuspl
Cytat(Pyton_000 @ 18.06.2017, 15:23:34 ) *
Wyraźnie napisałem że masz zrobić 2x left join do personel za każdym razem nadając mu inny alias, i w select potem sobie wyciągasz po tych aliasach.


OK. Dzięki wielkie! thumbsupsmileyanim.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.