Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> wszyukiwanie w tabelach połączonych
Gizypl
post 28.03.2014, 12:28:15
Post #1





Grupa: Zarejestrowani
Postów: 14
Pomógł: 0
Dołączył: 13.09.2012

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


Witam serdecznie.

Gdzieś się zamieszałem w logice bazy czy zapytaniu a może jakieś zaćmienie ?!

Mam 3 tabele TEMATY , TAGI i łaczącą poprzednie tabele TEMATY_TAGI gdzie są pary tematID i tagID
czyli do danego tematu są przypisane jakieś tagi po przez podanie w tabeli TEMATY_TAGI rekordu zawierającego id tematu id tagu - standard

i teraz chciał bym wyciągnać z tego informacje -> temat który zawiera podane tagi
czyli
w skrócie selec where tag1 and tag2 and tag3 - co daje mi pusty wynik mimo iż podane powiązania są wprowadzone
wersja z lub czyli select where tag1 or tag2 or tag3 daje już wyniki ale mi chodzi o zawężenie wyszukiwania
czyli temat który ma przypożądkowany tag1 i tag2 i tag3 a nie ten albo ten.
Gdzie się zamotałem questionmark.gif To chyba jakiś błąd logiki - pomocy ?

ale teraz zapytanie:

  1. SELECT
  2. tematy.tematNazwa,
  3. tagi.nazwa
  4. FROM
  5. tematy INNER JOIN
  6. tematy_tagi ON tematy.tematID = tematy_tagi.tematID INNER JOIN
  7. tagi ON tematy_tagi.tagID = tagi.ID
  8. WHERE
  9. tagi.nazwa = 'rower' AND
  10. tagi.nazwa = 'sport'
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 8)
nospor
post 28.03.2014, 12:33:01
Post #2





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




tagi.nazwa = 'rower' AND tagi.nazwa = 'sport'
Trudno oczekiwac aby tag jednoczesnie mial wartosc ROWER i SPORT...... O LUB nie slyszal?

No chyba ze chcesz by dany temat mial wszyskie podane tagi a nie jakikolwiek z nich. Wowczas musisz zrobic tyle JOIN na TAGI ile tagow szukasz i warunek AND dawac na kazdego JOIN a nie jak teraz ze wszystko w ramach jednego JOIN masz


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

"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
Gizypl
post 28.03.2014, 12:59:27
Post #3





Grupa: Zarejestrowani
Postów: 14
Pomógł: 0
Dołączył: 13.09.2012

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


Chodzi mi własnie o wersje temat i jego wszystkie tagi ale jakoś nie mogę sobie wyobrazić podanej przez ciebie konstrukcji - mógł byś rozwinąć myśl - lub jakiś przykładzik
Pozdro
Go to the top of the page
+Quote Post
bpskiba
post 28.03.2014, 21:30:14
Post #4





Grupa: Zarejestrowani
Postów: 340
Pomógł: 49
Dołączył: 3.07.2009
Skąd: Rzeszów

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


  1. ....
  2. JOIN tagi t1 ON tematy_tagi.tagID = t1.ID
  3. JOIN tagi t2 ON tematy_tagi.tagID = t2.ID
  4. WHERE
  5. t1.nazwa='rower' AND
  6. t2.nazwa='sport'


jedną tabelę można dołączyć wielokrotnie, ale wymaga to używania aliasów

można też użyć funkcji exists
http://dev.mysql.com/doc/refman/5.0/en/exi...subqueries.html

można kombinować z grupowaniem oraz HAVING

rozwiązań może być wiele

Ten post edytował bpskiba 28.03.2014, 21:34:28
Go to the top of the page
+Quote Post
Gizypl
post 2.04.2014, 22:50:43
Post #5





Grupa: Zarejestrowani
Postów: 14
Pomógł: 0
Dołączył: 13.09.2012

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


Dzięki - aktualnie walczę z tematem
Go to the top of the page
+Quote Post
pmir13
post 2.04.2014, 23:44:59
Post #6





Grupa: Zarejestrowani
Postów: 282
Pomógł: 89
Dołączył: 12.04.2011

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


W najprostszym podejściu, jeśli chcemy znaleźć tylko ID tematów posiadających wszystkie podane tagi (przykładowo tagi o ID 1 i 2) robimy to tak:

  1. SELECT tematID
  2. FROM tematy_tagi
  3. WHERE tagID=1
  4. OR tagID=2
  5. GROUP BY tematID
  6. HAVING COUNT(*)=2


Rozbudowując to o nazwy pobrane z innych tabel mamy:

  1. SELECT tematy.tematNazwa,
  2. ttg.lista_tagow
  3. FROM tematy
  4. JOIN
  5. (
  6. SELECT tt.tematID,
  7. GROUP_CONCAT( tg.nazwa ) AS lista_tagow,
  8. COUNT(*) AS pasujacych_tagow
  9. FROM tematy_tagi tt
  10. JOIN tagi tg
  11. ON tt.tagID = tg.ID
  12. WHERE tg.nazwa = 'rower'
  13. OR tg.nazwa = 'sport'
  14. GROUP BY tt.tematID
  15. HAVING pasujacych_tagow = 2
  16. ) ttg
  17. ON tematy.tematID = ttg.tematID
Go to the top of the page
+Quote Post
mmmmmmm
post 3.04.2014, 07:44:25
Post #7





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

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


Wszystko OK, ale zapomniałeś o DISTINCT. Powinno być w pierwszym HAVING Count(DISTINCT tagID)=2, a w drugim Count(DISTINCT tagID) AS pasujacych_tagow
Go to the top of the page
+Quote Post
pmir13
post 3.04.2014, 10:17:12
Post #8





Grupa: Zarejestrowani
Postów: 282
Pomógł: 89
Dołączył: 12.04.2011

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


Założyłem jedynie, że dla danego tematu ten sam tag nie będzie dodany wielokrotnie. Gdyby się powtarzały distinct faktycznie byłoby niezbędne. Ale czy będziemy mieli temat z tagami 'sport', 'sport', 'rower', 'rower', 'rower'? W większości podobnych przypadków, czyli ogólnie sztucznych tabel łączących dwie inne tabele w celu uzyskania relacji wiele do wielu, pary id z obu tabel są unikalne, a zrobienie z takiej pary klucza głównego zamiast osobnego autoinkrementowanego id jest całkiem dobrym pomysłem. Wtedy nawet próba powtórzenia jakiegoś tagu dla tego samego tematu zakończy się błędem.
Go to the top of the page
+Quote Post
mmmmmmm
post 3.04.2014, 11:30:08
Post #9





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

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


Fakt. Ja już wybiegłem trochę do przodu - do tagów z wagami smile.gif
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 Wersja Lo-Fi Aktualny czas: 14.08.2025 - 08:05