Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> GROUP BY - problem z grupwaniem rekordów
modo
post
Post #1





Grupa: Zarejestrowani
Postów: 3
Pomógł: 0
Dołączył: 5.06.2007

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


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 ';
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 5)
JoShiMa
post
Post #2





Grupa: Zarejestrowani
Postów: 1 374
Pomógł: 149
Dołączył: 1.03.2006

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


Może zainteresuj się klauzulą HAVING


--------------------
Go to the top of the page
+Quote Post
modo
post
Post #3





Grupa: Zarejestrowani
Postów: 3
Pomógł: 0
Dołączył: 5.06.2007

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


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...

Ten post edytował modo 21.10.2008, 09:31:07
Go to the top of the page
+Quote Post
thm
post
Post #4





Grupa: Zarejestrowani
Postów: 52
Pomógł: 10
Dołączył: 6.10.2008
Skąd: Lublin

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


nie jestem pewien czy dobrze rozumiem:
Kod
having max(sortowanie)

?
Go to the top of the page
+Quote Post
modo
post
Post #5





Grupa: Zarejestrowani
Postów: 3
Pomógł: 0
Dołączył: 5.06.2007

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


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.
Go to the top of the page
+Quote Post
osiris
post
Post #6





Grupa: Zarejestrowani
Postów: 121
Pomógł: 15
Dołączył: 19.07.2007

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


  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)

Ten post edytował osiris 26.10.2008, 12:50:48
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: 20.08.2025 - 16:41