Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: wszyukiwanie w tabelach połączonych
Forum PHP.pl > Forum > Bazy danych > MySQL
Gizypl
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'
nospor
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
Gizypl
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
bpskiba
  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
Gizypl
Dzięki - aktualnie walczę z tematem
pmir13
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
mmmmmmm
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
pmir13
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.
mmmmmmm
Fakt. Ja już wybiegłem trochę do przodu - do tagów z wagami smile.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.