Powiązania danych pokrewieństwem w PHP
Załóżmy, że stoi przed nami zadanie przechowywania ojców i synów. Niech każdy ojciec może mieć tylko jednego syna, a syn z kolei też może mieć jednego syna.
Trzeba wymyślić, jak będziemy przechowywać dane.
Pierwszy pomysł, który może przyjść do głowy
- stworzyć dwie tabele: parents dla
ojców i sons dla synów. Następnie powiązać
te tabele jakimś polem: son_id
lub parent_id.
Jednakże, ten pomysł nie jest zbyt dobry - przecież ta sama osoba może być jednocześnie ojcem i synem - i trzeba będzie ją przechowywać w obu tabelach, a to jest niewygodne, zajmuje więcej miejsca i łatwo prowadzi do błędów.
Lepszym wariantem - jest powiązanie tabeli samej
ze sobą: stwórzmy tabelę users, w
niej będziemy przechowywać wszystkich użytkowników i każdemu zrobimy
pole son_id, w którym będzie przechowywane
id syna z tej samej tabeli:
| id | name | son_id |
|---|---|---|
| 1 | user1 | 2 |
| 2 | user2 | 3 |
| 3 | user3 | null |
Zapytania
Napiszmy teraz zapytanie, które pobierze użytkownika razem z jego synem.
Na początek po prostu pobierzmy użytkowników:
SELECT
*
FROM
users
Teraz dołączmy (zjoinujmy) do użytkowników ich synów. Dołączanie (joinowanie) będziemy wykonywać tabeli samej do siebie, dlatego musimy wykonać jej zmianę nazwy:
LEFT JOIN users as sons
Teraz możemy wskazać powiązanie tabeli głównej i tabeli ze zmienioną nazwą:
LEFT JOIN users as sons ON sons.id=users.son_id
Wskażmy teraz pola:
SELECT
users.name as user_name, sons.name as son_name
Złóżmy wszystko razem i otrzymamy następujące zapytanie:
SELECT
users.name as user_name, sons.name as son_name
FROM
users
LEFT JOIN users as sons ON sons.id=users.son_id
Zadania praktyczne
Załóżmy, że mamy kategorie. Każda kategoria może należeć do kategorii nadrzędnej (rodzica), ta z kolei do swojej kategorii nadrzędnej i tak dalej. Opisz strukturę przechowywania.
Napisz zapytanie, które pobierze kategorię razem z jej kategorią nadrzędną (rodzicem).
Napisz zapytanie, które pobierze kategorię razem z jej rodzicem i rodzicem rodzica (dziadkiem).
Napisz zapytanie, które pobierze kategorię razem z jej rodzicem, dziadkiem i pradziadkiem.