Group by mit Limitierung?

ThiKool

Erfahrenes Mitglied
Hi Leute,

ich bastle gerade an einem SQL und habe folgendes Problem:
Ich möchte jeweils die drei Wochenbesten aus einer Tabelle lesen, sprich es sollen maximal 6 Datensätze ausgelesen werden, es kann aber auch sein das in der Vorwoche nur 2 Teilgenommen haben oder eben auch z.B. 5.

Bei fünf siehts so aus:

woche 1
1.
2.
3.
4.
5.

woche 2
1.
(da limit 6 ist)

für Woche 1 sollten aber maximal 3 Datensätze ausgegeben werden.

Bekommt man das mit einem Select hin?

Habs schon mit Group by, having und einer Bedingung im SQL versucht:
@count_last_week := IF(@last_week = week, @count_last_week + 1, @count_last_week) AS count_last_week,

leider ohne Erfolg
 
es scheint sich um MySQL zu handeln.

Leider komme ich absolut nicht draus, was du haben willst.

Mach mir bitte ein Datenbeispiel mit Tabellen. So in der Art:
Das hab ich:
Code:
Tabelle mitarbeiter
id | firma_id | name
--------------------
1 | 1 | MA1
2 | 1 | MA2
3 | 2 | MA3

Tabelle Firma
id | name
---------------------
1 | firma1
2 | firma2

Nun will ich wissen, welche Firma wieviele Mitarbeiter hat. Das soll dann so aussehen
Code:
firma_id | firma_name | anzahl_mitarbeiter
------------------------------------------
1 | firma1 | 2
2 | firma3 | 1
 
Hi,
sorry dafür, also pass auf:

Code:
Tabelle work
id | user_id | week | hours_worked
--------------------
1 | 1 | 8 | 12
2 | 2 | 8 | 20
3 | 3 | 8 | 17
4 | 4 | 8 | 12
5 | 5 | 8 | 27
6 | 6 | 8 | 40
7 | 1 | 9 | 5
8 | 2 | 9 | 54
9 | 3 | 9 | 33
10 | 4 | 9 | 11

Jetzt möchte ich mit einem Select maximal 3 User sortiert nach Arbeitszeit pro Woche ausgeben - sprich ich möchte so ein array:

Code:
array(
    8 => array(
        6 => array(
            'work_time' => 40
        ),
        5 => array(
            'work_time' => 27
        ),
        2 => array(
            'work_time' => 20
        )
    ),
    9 => array(
        2 => array(
            'work_time' => 54
        ),
        3 => array(
            'work_time' => 33
        ),
        4 => array(
            'work_time' => 12
        )
    )
);

Ja es soll über MySQL laufen.

Vielen Dank schonmal :)
 
Jetzt versteh ich, was du haben willst.

SQL:
select 
	d.week, 
	d.user_id, 
	d.hours_worked
from
  (
    select 
      w.user_id, 
		w.week, 
		w.hours_worked,
      @rank := if(@last_row_week = w.week, @rank+1, 1) as rank,
      @last_row_week := w.week AS act_week
    from 
      (	
			select s.* 
			from work s 
			order by s.week, s.hours_worked desc
		) w,
      (select @rank := 0, @last_row_week := 0) v
    ) d
 where d.rank <= 3
 
Ahhh, verdammt, da war ich wirklich nah dran.

Meine Variante hat dann nicht mehr funktioniert wenn z.B. (aus welchen Gründen auch immer) ein Eintrag von Woche 9 vor Woche 8 eingefügt wurde also so z.B.

Code:
Tabelle work
id | user_id | week | hours_worked
--------------------
1 | 1 | 8 | 12
2 | 1 | 9 | 20
3 | 3 | 8 | 17
...

Ist das jetzt performanter als je ein eigener Select oder wäre das eh irrelevant bei dieser Datenmenge gewesen`?

Vielen Dank
 
Ist das jetzt performanter als je ein eigener Select oder wäre das eh irrelevant bei dieser Datenmenge gewesen`?
Ich kenne jetzt "die" Datenmenge nicht. Aber ich denke, für eine kleine bis mittlere Tabelle kommts nicht drauf an.
Wenn die iNdexe gut gesetzt sind, kann ich mir denken, dass es schneller ist als für jede Woche eine eigene Abfrage aus PHP abzusenden.
 
Zurück