Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: GROUP BY - problem z grupwaniem rekordów
Forum PHP.pl > Forum > Bazy danych > MySQL
modo
Mam problem z zapytaniem SQL, a konkretnie GROUP BY. Skrypt wyszukuje w bazie rekordy, ktore najelpiej pasuja do szukanego slowa ($search) pod wzgledem h1, title pomnozone przez odpowiednie liczby-parametry. Rekordy powinny byc wybrane z bazy, jesli sortowanie>0.
Wyszukane rekordy grupuje wg tytulu. Nie wszystkie rekordy danej grupy jednak spelniaja warunek sortowanie>0. Jesli jednak ktorys z rekordow go spelnia to i tak laczy sie z reszta rekordow danej grupy. Wynikiem sa pola description, title, link, date odpowiednie dla pierwszego rekordu danej grupy. A chcialbym, aby byly one dla rekordu z grupy o najwiekszej wartosci sortowanie.

Jak mam to zrobic? Ponizej fragment kodu. Prosze o pomoc.


  1. $query='SELECT
  2.  
  3. description, title, link, date,
  4.  
  5. max(MATCH (h1) AGAINST (''.mysql_escape_string($search).'' IN BOOLEAN MODE) * '.$param['h1'].' +
  6.  
  7. MATCH (title) AGAINST (''.mysql_escape_string($search).'' IN BOOLEAN MODE) * '.$param['title'].)
  8.  
  9. * ( (pagerank) * '.$param['pagerank'].') AS sortowanie
  10.  
  11. FROM site WHERE STATUS =1
  12.  
  13. GROUP BY title
  14.  
  15. ORDER BY sortowanie DESC ';
JoShiMa
Może zainteresuj się klauzulą HAVING
modo
próbowałem dać GROUP BY title HAVING sortowanie>0
ale dla grupy jest to prawda, jeśli tylko jeden rekord spełnia ten warunek...
thm
nie jestem pewien czy dobrze rozumiem:
Kod
having max(sortowanie)

?
modo
nie bardzo działa...
a może w ten sposób, żeby zapytanie pobierało z tabeli rekordy o różnych wartościach pola title ale tych o największej wartości sortowanie? może da się to zrobić bez GROUP BY, ale z użyciem DISTINCT? jeśli tak to jak dokładnie? próbowałem, ale niebardzo...

Próbowałem już różnych zapytań i nadal nic nie wychodzi.
Może przedstawię to jaśniej i może ktoś będzie wiedział, jak się z tym uporać.

Mam tabelę site:

+----+-------+------------+------+
| id | title | link | body |
+----+-------+------------+------+
| 1 | str1 | str1/1.htm | aaa |
| 2 | str1 | str1/2.htm | xxx |
| 3 | str1 | str1/3.htm | bbb |
| 4 | str2 | str2/1.htm | ccc |
| 5 | str2 | str2/2.htm | xxx |


Zmianna $search='xxx';

Wynikiem powinno byc:

+----+-------+------------+------+
| id | title | link | body |
+----+-------+------------+------+
| 2 | str1 | str1/2.htm | xxx |
| 5 | str2 | str2/2.htm | xxx |


Próbowałem:
  1. $query=mysql_query('
  2.  
  3. SELECT title, link,
  4.  
  5. max(MATCH (body) AGAINST (''.mysql_escape_string($search).'' IN BOOLEAN MODE) * '.$param['body'].') as sortowanie
  6.  
  7. FROM site GROUP BY title HAVING sortowanie >0
  8.  
  9. ORDER BY sortowanie DESC ');


Ale to łączy wszystkie rekordy wg title jeśli tylko jeden spełnia warunek sortowanie>0 (przez co pola link, body są dowolne).

Jeszcze raz proszę o pomoc.
osiris
  1. CREATE TEMPORARY TABLE tmatches1 (SELECT *, MATCH (body) AGAINST (\''.mysql_escape_string($search).'' IN BOOLEAN MODE) * '.$param['body'].' as rank FROM site); CREATE TEMPORARY TABLE tmatches2 (SELECT * FROM tmatches1); SELECT * FROM tmatches1 AS m1 WHERE rank = (SELECT MAX(rank) FROM tmatches2 WHERE title = m1.title);
  2.  
  3. DROP TABLE tmatches1, tmatches2;


lub

  1. SELECT *, MATCH (body) AGAINST (\''.mysql_escape_string($search).'' IN BOOLEAN MODE) * '.$param['body'].' ) AS rank
  2. FROM site AS s1 WHERE rank = (
  3. SELECT MAX(MATCH (body) AGAINST (''.mysql_escape_string($search).'' IN BOOLEAN MODE) * '.$param['body'].' ) FROM site WHERE title = s1.title
  4. );


albo

  1. SELECT *
  2. FROM site AS s1
  3. LEFT JOIN (SELECT title , MAX(MATCH (body) AGAINST (\''.mysql_escape_string($search).'' IN BOOLEAN MODE) * '.$param['body'].' )) AS max_rank FROM site GROUP BY title) AS s2 ON s1.title = s2.title AND s2.max_rank = MATCH (body) AGAINST (''.mysql_escape_string($search).'' IN BOOLEAN MODE) * '.$param['body'].' ;


To ktore rozwiazanie bedzie najszybsze pozostawiam Tobie do sprawdzenia.
W pierwszym przypadku druga tabela tymczasowa jest potrzebna poniewaz MySQL-owe tabele tymczasowe maja takie ograniczenie, ze nie moga byc uzyte dwa razy w jednym zapytaniu (tt - tabela tymczasowa: SELECT ... FROM tt WHERE ... = (SELECT ... FROM tt WHERE ...) nie zadziala)
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.