Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]połączenie dwóch tabel
Forum PHP.pl > Forum > Przedszkole
casperii
Panowie mam pytanie odnośnie pobierania informacji z dwóch tabel , jak to wykonać optymalnie ?

tabela: grupa:
id, grupa
1 klienci
2 sprzedawcy
3 inni

tabela uzytkownicy
id, user, grupa
1 czesiek, klienci
2 franek , klienci
3 staszek, sprzedawcy
4 zygmunt, klienci

teraz chce wyświetlić wszystko z tabelki grupa
  1. select * from grupa


powyższe zapytanie wyświetli mi
klienci
sprzedawca

a Ja chciałbym osiągnąć taki schemat:
klienci:
czesiek, franek, zygmunt
sprzedawcy:
staszek

ktoś podpowie ? Oczywiście tych grup może być bardzo dużo , chodzi mi raczej o zrozumienie tego.

Nie wiem , czy w dobrą stronę idę:

  1. SELECT * FROM `uzytkownicy` AS `u` WHERE `u`.`grupa` IN ( SELECT g.grupa FROM grupa g WHERE `u`.`grupa` = `g`.`grupa` )


teraz wyświetla mi to co ma powiązania w dwóch tabelach i nie mam tak jak by nagłówka grupy.

klienci:
czesiek, franek, zygmunt
sprzedawcy:
staszek
inni:

kolor pogrubiony czarny - to pokazuje
kolor czerwony - tego nie pokazuje a chce by też pokazywało nawet jeśli nie ma relacji
kolor fioletowy - tego też nie pokazuje gdyż w tabeli klienci nie ma powiązania , a chce by też wyświetlało.

Ewentualnie jak to zrobić w php ?
Neutral
MariaDB [casperii]> select * from users;
+----+---------+---------+
| id | user | col2 |
+----+---------+---------+
| 1 | czesiek | clients |
| 2 | franek | clients |
| 3 | staszek | seller |
| 4 | staszek | clients |
+----+---------+---------+

  1. SELECT clients,seller,other FROM (SELECT (case when col2='clients' then user end) AS clients
  2. , (case when col2='seller' then user end) AS seller
  3. , (case when col2='other' then user end) AS other FROM users) AS derived_table;


+---------+---------+-------+
| clients | seller | other |
+---------+---------+-------+
| czesiek | NULL | NULL |
| franek | NULL | NULL |
| NULL | staszek | NULL |
| staszek | NULL | NULL |
+---------+---------+-------+
SmokAnalog
Źle się za to zabierasz. Powiedz dokładnie co chcesz zrobić. Dlaczego nie wystarczy Ci zwyczajny JOIN z użytkownikami posortowanymi według grupy? Ewentualnie możesz pomyśleć o użyciu GROUP_CONCAT.
casperii
@SmokAnalog efekt który chce osiągnąć ma być na zasadzie kategorii i wyświetlonej liście produktów

czyli zakładamy , że mamy dwie tabele:

tabelka kategorie
id, kategoria, nazwałączenia
1. Komputery , KMP-1
2. RTV , RTV-2
3. Motoryzacja, MOT-3

tabelka produkty
id, nazwa, nazwałączenia, cośtam coś
1. Romet, MOT-3, okazja
2. Laptop, KMP-1, promocja
3. Telewizor, RTV-2, wyprzedaż
4. DVD, RTV-2, okazja

Chce mieć listę na wzór

Komputery (1):
-Laptop okazja

Motoryzacja (1):
-Romet, okazja

RTV (2):
-Telewizor, wyprzedaż
-DVD, okazja

i teraz tak sobie przemyślałem, że to jednak trzeba by było zrobić na zasadzie PHP. Masz pomysł ?
SmokAnalog
Tak myślałem. Ludzie często mylą format wyświetlania z formatem danych.

Pobierz te rekordy normalnie odpowiednio posortowane i w PHP sobie pogrupuj według danej kolumny (polecam array_reduce). Albo po prostu iteruj te wyniki sprawdzając co krok czy grupa się zmieniła. Jak się zmieniła, to wyświetl nagłówek. Pseudokod:

  1. Ustaw $grupę na null.
  2. Dla każdego wiersza z bazy:

    1. Jeżeli grupa z wiersza jest różna od $grupy, pokaż nagłówek grupy.
    2. Pokaż wiersz.
casperii
@SmokAnalog dzięki za podpowiedź, a czy mógłbyś mi rozpisać schemat?

na pewno select * kategorie order by kategoria ASC
i co dalej foreach i w nim odwołanie do każdej kategorii dla drugiej tabelki ?
SmokAnalog
Zwykły LEFT JOIN.

Albo może zrób sobie po prostu dwa osobne zapytania? Zbierz kategorie do tablicy, potem zrób tak:

  1. $categories = array_map(function ($category) {
  2. $category->products = [];
  3. }, array_combine(array_column($categories, 'id'), $categories));


I w końcu albo w array_map, albo w pętli (żeby oszczędzić pamięć) połącz poszczególne produkty z kategoriami:

  1. $categories[$product->category_id]->products[] = $product;


Sposobów jest mnóstwo. Wykonasz albo jedno, albo dwa zapytania. Skłaniałbym się nawet lekko ku dwóm.
casperii
@SmokAnalog czyli że tak? :


  1. $sql = $pdo->prepare("select * from `kategorie` ORDER BY `kategoria` ASC");
  2. $sql2 = $pdo->prepare("select * from `produkty` ORDER BY `nazwa` ASC");
  3. try {
  4. $sql->execute();
  5. $row = $sql->fetchAll(PDO::FETCH_OBJ);
  6.  
  7. $sql2->execute();
  8. $row2 = $sql2->fetchAll(PDO::FETCH_OBJ);
  9.  
  10. $categories = array_map(function ($category) { // $category to jest nasz array czyli $row ?
  11. $category->products = [];
  12. }, array_combine(array_column($categories, 'id'), $categories));
  13.  
  14. while(){ // co powinienem wsadzić w tym przypadku do pętli while ?
  15. $categories[$product->category_id]->products[] = $product; //$product to nasze $row2 ?
  16. }
  17.  
  18. }catch(PDOException $e){
  19. echo $e->getMessage();
  20.  
  21. }
SmokAnalog
Kategorie sobie pobierz z $sql->fetchAll(PDO::FETCH_OBJ). Zakładam, że te dane nie idą w jakieś grube tysiące, bo jeśli idą, to warto rozważyć fetch wiersz po wierszu.
casperii
Wolałbym wybiegać w przyszłość i zakładać , że może być kategorii 10000 smile.gif
SmokAnalog
Będziesz miał stronę, która będzie pokazywała 10000 kategorii naraz?
casperii
No może 10000 kategorii to gruba przesada oneeyedsmiley02.png ale myśle, że max 500 to może się uzbierać
SmokAnalog
Ja bym to raczej wrzucił do tablicy zamiast fetchować, bo wygodniej się będzie na tym pracowało. Rozumiesz ideę? Chcemy zrobić tablicę kategorii, gdzie każda kategoria ma właściwość products, będącą tablicą jej produktów. Wtedy w widoku możesz elegancko iterować te kategorie i produkty każdej z nich.
casperii
@SmokAnalog czyli, że w ten sposób?:

  1.  
  2. $sql = $pdo->prepare("select * from `kategorie` ORDER BY `kategoria` ASC");
  3. $kategorie = $sql->fetchAll(PDO::FETCH_OBJ)
  4.  
  5. $sql2 = $pdo->prepare("select * from `produkty` ORDER BY `nazwa` ASC");
  6. $produkty = $sql->fetchAll(PDO::FETCH_OBJ)


i że powyższe teraz wrzucić w to?:

  1. $categories = array_map(function ($category) {
  2. $category->products = [];
  3. }, array_combine(array_column($categories, 'id'), $categories));
nospor
Tutaj
http://nospor.pl/grupowanie-wynikow.html
masz pokazane na dokladnie takim samym przykladzie co u ciebie: kategorie -> produkty
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-2024 Invision Power Services, Inc.