Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Newsy sortowanie po tagach
Forum PHP.pl > Forum > Bazy danych > MySQL
Eagle
Witam smile.gif

Potrzebuje pobrać wszystkie newsy które są przypisane do danego tagu wraz z tagami z jakimi został utworzony.

Mając w bazie
Kod
       ID | TREŚĆ | PRZYPISANETAGI
       1 | Treść pierwszego newsa | świat;dom;szklanka
       2 | Treść drugiego newsa | świat;czerwony
       3 | Inny news | czerwony;kolorowy;niebieski


i szukając newsa z takiem 'świat' potrzebuje wyświetlnić
Kod
       1 | Treść pierwszego newsa | świat;dom;szklanka
       2 | Treść drugiego newsa | świat;czerwony


Struktura
Kod
       News
       n_id
       tresc
      
       Tag
       tag_id - id
       tag_name - nazwa tagu (np.świat)
      
       News_tags (połączenie tagów z odpowiednim id)
       tag_id
       news_id


Używając zapytania
  1. SELECT `news` . * , GROUP_CONCAT( `tag`.`tag_name`
  2. ORDER BY `tag`.`tag_name`
  3. SEPARATOR ';' ) AS `tags`
  4. FROM `tag` LEFT JOIN `news_tags` ON `news_tags`.`tag_id` = `tag`.`tag_id`
  5. LEFT JOIN `news` ON `news`.`a_id` = `news_tags`.`n_id`
  6. WHERE `tag`.`tag_name` LIKE 'NAZWA_TAGU' OR `tag`.`tag_name` LIKE '%'
  7. GROUP BY `news`.`n_id`


Dostaje to o potrzebuje i dodatkowo bonusowo zwraca mi pusty news (same wartości null) wraz ze wszystkimi możliwymi tagami.
Kod
     NULL | NULL | świat;dom;szklanka;czerwony;kolorowy;konik;ble;zupa.....
     1 | Treść pierwszego newsa | świat;dom;szklanka
     2 | Treść drugiego newsa | świat;czerwony


Gdy zmienie zapytanie na:
  1. SELECT `news` . * , GROUP_CONCAT( `tag`.`tag_name`
  2. ORDER BY `tag`.`tag_name`
  3. SEPARATOR ';' ) AS `tags`
  4. FROM `tag` LEFT JOIN `news_tags` ON `news_tags`.`tag_id` = `tag`.`tag_id`
  5. LEFT JOIN `news` ON `news`.`a_id` = `news_tags`.`n_id`
  6. WHERE `tag`.`tag_name` LIKE 'świat' OR `tag`.`tag_name` LIKE '%' AND `news`.`n_id` != NULL
  7. GROUP BY `news`.`n_id`


To dostaje newsy które powinienem dostać, jednak w polu `tags` mają tylko jeden szukany tag zamiast wszystkich do których został przypisany.

Kod
     1 | Treść pierwszego newsa | świat
       2 | Treść drugiego newsa | świat


Może ktoś wie jak poprawić zapytanie ?
blooregard
Jeśli masz tabele MyISAM (nie InnoDB), czyli nie używasz transakcji, ustaw sobie na kolumnie z tagami index FULLTEXT i będziesz mógł wyszukiwać z niej dane przy pomocy przeszukiwania pełnotekstowego używając MATCH() ... AGAINST
To uprości Ci sprawę wyszukiwania.
Eagle
Niestety nie uprości. Większość tagów ma długość 3 znaków, wyszukiwanie potrzebuje co najmniej 4

Zastanawiam się bardziej jak wyeliminować pusty wpis który jest na początku wyników.

Edit:
Ustawiłem LIMIT 1,X i jakoś żyje.
Jeżeli ktoś ma inny pomysł rozwiązania to czekam na propozycje.


Edit2:
Właśnie się zastanawiam czemu jest FROM `tag` zamist FROM `news` ...
Po zmianie wszystko działa ok.
złowieszczy_pan
Ja wykombinowałem coś takiego... Mam identyczny układ tabel na swojej stronie, więc przetestowałem. Mam nadzieję, że nie popełniłem błędu w zamianie nazw pól tongue.gif

  1. SELECT M.`n_id` , M.`tresc` , (
  2. SELECT GROUP_CONCAT( T.`tag_id`
  3. ORDER BY T.`tag_id`
  4. SEPARATOR ';' ) AS `tags`
  5. FROM `Tag` T
  6. JOIN `News_tags` KT ON T.`n_id` = KT.`tag_id`
  7. WHERE KT.`news_id` = M.`n_id`
  8. )
  9. FROM `News` M
  10. JOIN `News_tags` MT ON M.`n_id` = MT.`news_id`
  11. WHERE MT.`tag_id` = (SELECT `tag_id` FROM `Tag` WHERE `tag_name` = 'NAZWA TAGA')


Ale nie wydaje mi się to optymalne tongue.gif hahaha biggrin.gif

Pozdrawiam
blooregard
Cytat
Niestety nie uprości. Większość tagów ma długość 3 znaków, wyszukiwanie potrzebuje co najmniej 4


Zmieniasz ustawienia w my.cnf i juz nie musi mieć 4 znaków:

[mysqld]
ft_min_word_len= [wartosc]
Eagle
@złowieszczy_pan:
Twoje zapytanie jest lepsze smile.gif
Bo moje przez % zwraca wszystkie tagi, wiec jakbym nic nie wyszukiwał tylko wyświetlał.
Trzeba pomyśleć jak to da się zoptymalizować (o ile się da ;P)

@blooregard
Tylko nie zawsze ma się odstęp do tego configa.
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.