Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> SELECT TOP 'n' RECORDS FROM EACH CATEGORY?
nTiger
post 11.09.2014, 10:00:03
Post #1





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

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


Witam, od paru dni probuje i probuje rozwiazac problem na ktory sie natknalem i stoje w miejscu, mianowicie potrzebuje uzyskac 2 rekordow o najnizszym czasie z kazdej kategorii.

Moje tabele wygladaja o tak:
  1. sr_id | category | map | time | short
  2. 0 100 map1 100 0
  3. 0 100 map1 200 0
  4. 0 100 map1 300 0
  5. 0 100 map2 100 0
  6. 0 100 map2 200 0
  7. 0 100 map2 300 0
  8. 0 200 map1 100 0
  9. 0 200 map1 200 0
  10. 0 200 map1 300 0
  11. 0 200 map2 100 0
  12. 0 200 map2 200 0
  13. 0 200 map2 300 0
  14. 0 333 map1 100 0
  15. 0 333 map1 200 0
  16. 0 333 map1 300 0
  17. 0 333 map2 100 0
  18. 0 333 map2 200 0
  19. 0 333 map2 300 0


chce wybrac po 2 najlepsze czasy z tabeli 'time' z kazdej kategorii z tabeli 'category', gdzie tabela 'map' = 'map1' czyli powinno to wygladac nastepujaco:

  1. sr_id | category | map | time | short
  2. 0 100 map1 100 0
  3. 0 100 map1 200 0
  4. 0 200 map1 100 0
  5. 0 200 map1 200 0
  6. 0 333 map1 100 0
  7. 0 333 map1 200 0


udalo mi sie wykonac 2 sposoby, lecz zaden nie dziala tak jak powinien, wygladaja one o tak:

  1. SELECT tabela_times.* FROM tabela_times JOIN (SELECT t1.category, t1.time, COUNT(t2.category) AS theCount
  2. FROM tabela_times t1 LEFT JOIN tabela_times t2 ON t1.category = t2.category AND t1.time > t2.time
  3. GROUP BY t1.category, t1.time ASC
  4. WHERE (theCount < 2)) AS dt USING (category, time);


To akurat smiga bez zazuty, lecz wyszukuje on z kazdej mapy, a ja potrzebuje tylko z mapy 'map1', wiem ze mogl bym dodac " WHERE map = 'map1' ", ale nie mam pojecia w ktorym miejscu to dodac.

Mam takze 2 rozwiazanie ktore dziala bez problemu: (ale)

  1. SET @oldGroup := 0, @count := 0; SELECT @oldGroup := category, tabela_times.* FROM tabela_times HAVING map = 'map1' AND short = '1' AND (@count := IF(category <=> @oldGroup, @count+1, 0)) < 15 ORDER BY category, time ASC;


ale przez to ze jest wywolana funkcja ( SET @oldGroup := 0, @count := 0; ) przed 'SELECT' moj plugin nie akceptuje juz niczego innego

Ten post edytował nTiger 11.09.2014, 10:01:16
Go to the top of the page
+Quote Post
Pyton_000
post 11.09.2014, 11:53:43
Post #2





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


Bo masz wykonać 2 zapytania oddzielnie, zapewne wrzucasz w PHP oba te zapytania razem.
Go to the top of the page
+Quote Post
mmmmmmm
post 11.09.2014, 12:05:03
Post #3





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

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


Dużo masz tych rekordów? Można to zrobić w czystym sql, ale może "trochę" zabić MySQL-a.
Go to the top of the page
+Quote Post
nTiger
post 11.09.2014, 15:28:17
Post #4





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

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


Cytat(Pyton_000 @ 11.09.2014, 11:53:43 ) *
Bo masz wykonać 2 zapytania oddzielnie, zapewne wrzucasz w PHP oba te zapytania razem.


Nie, nie robie tego w PHP, robie to w AMX MOD X


Cytat(mmmmmmm @ 11.09.2014, 12:05:03 ) *
Dużo masz tych rekordów? Można to zrobić w czystym sql, ale może "trochę" zabić MySQL-a.


No moze byc ich i 5,000+

Problem zalatwiony:

  1. SELECT tabela_times.* FROM tabela_times JOIN (SELECT t1.category, t1.time, SUM(case when t2.map = 'map1' THEN 1 ELSE 0 end) AS theCount
  2. FROM speedrun_v2_times t1 LEFT JOIN tabela_times t2 ON t1.category = t2.category AND t1.time > t2.time
  3. GROUP BY t1.category, t1.time
  4. HAVING (theCount < 1)) AS dt USING (category, time) WHERE map = 'map1' ORDER BY time ASC;


Ten post edytował nTiger 11.09.2014, 18:39:21
Go to the top of the page
+Quote Post
mmmmmmm
post 12.09.2014, 07:58:19
Post #5





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

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


  1. /*
  2. create table _mm_test
  3. (id int not null auto_increment primary key,
  4. sr_id int not null,
  5. category int not null,
  6. map varchar(10) not null,
  7. time int not null,
  8. short int not null);
  9.  
  10. insert into _mm_test(sr_id, category, map, time, short) values
  11. (0, 100, 'map1', 100,0),
  12. (0, 100, 'map1', 200,0),
  13. (0, 100, 'map1', 300,0),
  14. (0, 100, 'map2', 100,0),
  15. (0, 100, 'map2', 200,0),
  16. (0, 100, 'map2', 300,0),
  17. (0, 200, 'map1', 100,0),
  18. (0, 200, 'map1', 200,0),
  19. (0, 200, 'map1', 300,0),
  20. (0, 200, 'map2', 100,0),
  21. (0, 200, 'map2', 200,0),
  22. (0, 200, 'map2', 300,0),
  23. (0, 333, 'map1', 100,0),
  24. (0, 333, 'map1', 200,0),
  25. (0, 333, 'map1', 300,0),
  26. (0, 333, 'map2', 100,0),
  27. (0, 333, 'map2', 200,0),
  28. (0, 333, 'map2', 300,0);
  29. */
  30. SELECT sr_id, category, map, time, short FROM
  31. (
  32. SELECT *, (SELECT count(*) FROM _mm_test WHERE map=t.map AND category=t.category AND time<t.time) ranking FROM _mm_test t WHERE map='map1'
  33. ) sub
  34. WHERE ranking<2
Go to the top of the page
+Quote Post
nTiger
post 14.09.2014, 13:20:09
Post #6





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

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


Cytat(mmmmmmm @ 12.09.2014, 07:58:19 ) *
  1. /*
  2. create table _mm_test
  3. (id int not null auto_increment primary key,
  4. sr_id int not null,
  5. category int not null,
  6. map varchar(10) not null,
  7. time int not null,
  8. short int not null);
  9.  
  10. insert into _mm_test(sr_id, category, map, time, short) values
  11. (0, 100, 'map1', 100,0),
  12. (0, 100, 'map1', 200,0),
  13. (0, 100, 'map1', 300,0),
  14. (0, 100, 'map2', 100,0),
  15. (0, 100, 'map2', 200,0),
  16. (0, 100, 'map2', 300,0),
  17. (0, 200, 'map1', 100,0),
  18. (0, 200, 'map1', 200,0),
  19. (0, 200, 'map1', 300,0),
  20. (0, 200, 'map2', 100,0),
  21. (0, 200, 'map2', 200,0),
  22. (0, 200, 'map2', 300,0),
  23. (0, 333, 'map1', 100,0),
  24. (0, 333, 'map1', 200,0),
  25. (0, 333, 'map1', 300,0),
  26. (0, 333, 'map2', 100,0),
  27. (0, 333, 'map2', 200,0),
  28. (0, 333, 'map2', 300,0);
  29. */
  30. SELECT sr_id, category, map, time, short FROM
  31. (
  32. SELECT *, (SELECT count(*) FROM _mm_test WHERE map=t.map AND category=t.category AND time<t.time) ranking FROM _mm_test t WHERE map='map1'
  33. ) sub
  34. WHERE ranking<2


mmmmmmm, jestes wielki!

Ten post edytował nTiger 14.09.2014, 14:34:05
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: 23.06.2025 - 05:42