Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Tabele referencyjne i relacje many-to-many
maciej.m
post
Post #1





Grupa: Zarejestrowani
Postów: 12
Pomógł: 0
Dołączył: 9.02.2008

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


Witam,

Mam problem, z którym już pewnie się spotkaliście. Otóż dla dwóch tabel: a i b stworzyłem tabelę referencyjną x. W tabeli b ma się tak do tabeli a, że każdemu rekordowi z a może odpowiadać jeden lub kilka rekordów z b. Do określenia tej relacji służy tabela x, która zawiera pary a.id i b.id. Praktyczne zastosowanie tej struktury ma wyglądać tak, że przy wyciąganiu rekordów z tabeli a, do każdego takiego rekordu powinno być przyporządkowane jeden lub więcej rekordów z b. Pytanie w jaki sposób to praktycznie zrobić, żeby było jak najbardziej optymalnie i wydajnie.

Dla tego przykładu teraz mógłbym wykonać jedno zapytanie:
  1. SELECT * FROM `x` LEFT JOIN `a` ON (a.id = x.a_id) LEFT JOIN `b` ON (b.id = x.b_id);


Takie zapytanie oczywiście dawałoby mi zduplikowane rekordy z `a` z różną wartością pól dołączonych z `b`.

Mógłbym też wyciągać pojedyncze rekordy z `a` i dla każdego z nich stosować osobne zapytanie o pary, w których występuje z `b`

Czy macie na to jakieś praktyczne rozwiązanie?

--
Pozdrawiam
MM
Go to the top of the page
+Quote Post
darko
post
Post #2





Grupa: Zarejestrowani
Postów: 2 885
Pomógł: 463
Dołączył: 3.10.2009
Skąd: Wrocław

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


select distinct


--------------------
Nie pomagam na pw, tylko forum.
Go to the top of the page
+Quote Post
nospor
post
Post #3





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




to zapytanie jest bez sensu, bo jesli dla a nie bedzie przypisanego zadnego b, to nie wyciągnie ci tych a. No chyba ze o to ci wlasnie chodzilo.
Jesli nie o to, to zapytanie powinno wygladac tak:
  1. SELECT * FROM `a` LEFT JOIN `x` ON (a.id = x.a_id) LEFT JOIN `b` ON (b.id = x.b_id);


A w czym problem masz teraz? Jesli chodzi ci o grupowanie to:
http://nospor.pl/grupowanie-wynikow-n35.html


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
maciej.m
post
Post #4





Grupa: Zarejestrowani
Postów: 12
Pomógł: 0
Dołączył: 9.02.2008

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


Rzeczywiście, zapytanie lepsze. Tyle, że wyciąga mi zduplikowane rekordy w sytuacji jeżeli występuje wiele par pojedynczego `a` z różnymi `b`. Nie wiem jak to się ma do wydajności.
Załóżmy, że `a` to `pracownicy` a `b` to ich `pozytywne_cechy`. Teraz chcemy wyciągnąć listę pracowników i przy każdym zobaczyć listę ich pozytywnych cech.
Czy obrabianie takich danych powinno się odbyć na poziomie PHP po otrzymaniu wyników podanego zapytania, czy też na poziomie SQL z zastosowaniem jakiegoś sprytnego zapytania.

--
Pozdrawiam
MM

Jak by wyglądało takie zapytanie z SELECT DISTINCT?
Go to the top of the page
+Quote Post
nospor
post
Post #5





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




Cytat
Tyle, że wyciąga mi zduplikowane rekordy w sytuacji jeżeli występuje wiele par pojedynczego `a` z różnymi `b`.
zgadza sie, jest to naturalna sytuacja dla takich relacji.

Cytat
Czy obrabianie takich danych powinno się odbyć na poziomie PHP po otrzymaniu wyników podanego zapytania, czy też na poziomie SQL z zastosowaniem jakiegoś sprytnego zapytania.
W linku co ci dalem w poprzednim poscie masz opisane oba przypadki: obrobka w php i obrobka w mysql (uzycie GROUP_CONCAT)

Cytat
Jak by wyglądało takie zapytanie z SELECT DISTINCT?
DISTINCT sluzy czemu innemu i tu sie nie sprawdzi.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
maciej.m
post
Post #6





Grupa: Zarejestrowani
Postów: 12
Pomógł: 0
Dołączył: 9.02.2008

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


Ok, spróbowałem na podstawie tego postu skonstruować jakieś zapytanie, ale nie bangla: wyciąga jeden rekord ze zduplikowaną zawartością nowego pola. Oto zapytanie:

  1. SELECT GROUP_CONCAT( b.nazwa
  2. ORDER BY b.name ASC
  3. SEPARATOR ';;;' ) grupa, a. *
  4. FROM a
  5. LEFT JOIN x ON ( a.id = x.a_id )
  6. LEFT JOIN b ON ( b.id = x.b_id )
  7. LIMIT 0 , 30
Go to the top of the page
+Quote Post
nospor
post
Post #7





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




funkcje GROUP_CONCAT stosuje sie razem z GROUP BY ktorego ty nie raczyles dodac smile.gif


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
maciej.m
post
Post #8





Grupa: Zarejestrowani
Postów: 12
Pomógł: 0
Dołączył: 9.02.2008

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


No pięknie. Gra.

Całe moje zapytanie wygląda teraz tak (dodałem też WHERE)

  1. SELECT GROUP_CONCAT( b.nazwa
  2. ORDER BY b.name ASC
  3. SEPARATOR ';;;' ) grupa, a. *
  4. FROM a
  5. LEFT JOIN x ON ( a.id = x.a_id )
  6. LEFT JOIN b ON ( b.id = x.b_id )
  7. WHERE a.id = 51
  8. GROUP BY a.id
  9. ORDER BY a.nazwa ASC
  10. LIMIT 0 , 30


Stokrotne Dzięki
MM
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 21.08.2025 - 06:08