2017-03-23 1 views
0

meine einfache Tabelle auf diese Weise formatiert ist (4 Felder) und mehr als 100 Zeilen:Mysql Abfrage auf Ergebnisse Spiel funktioniert nicht

id Ergebnis ID_USER Daten

1 0 11 2016-10-15 18: 00:00
2 0 13 2016-10-15 18:00:00
3 0 16 2016-10-15 18:00:00
4 0 24 2016-10-15 18:00:00
5 0 6 2016 -10-15 18:00:00
6 3 5 2016-10-15 18:00:00
7 3 45 2016-10-15 18:00:00
8 3 66 2016-10-15 18:00: 00
9 3 4 2016-10-15 18:00:00
10 3 33 2016-10-8 17:00:00
11 1 55 2016-10-8 17:00:00
12 1 101 2016-10-8 17:00:00

....

I 10 Datensatz mit dieser Logik jede Woche sparen: Wenn ein Team gewinnt, spare ich 3 Punkte für jedes Teammitglied und 0 Punkte für jedes Mitglied der Teamlooser. (Wenn sie zeichnen, speichere ich 1 Punkt für alle 10 Mitglieder) und so weiter.

Jetzt ist meine Frage, wie man die ersten 3 Spieler, die in dieser Tabelle gespeichert wurden, die mindestens 5 Spiele und in den letzten 5 Spielen die Hauptpunkte hatte, extrahiert hat.

formatierte ich meine Abfrage auf diese Weise:

(SELECT m1.id_user, m1.data, SUM(result) AS ris 
FROM my_table m1 
JOIN(SELECT id_user 
     FROM my_table 
     GROUP BY id_user 
     HAVING COUNT(id_user) >= 5) m2 
ON m2.id_user = m1.id_user 
GROUP BY id_user 
ORDER BY m1.data DESC) 
ORDER BY ris DESC LIMIT 3; 

Aber diese Abfrage tha Menge von Punkten in allen Spielen gespielt und nicht nur in den letzten 5 Spielen betrachten! Wie kann diese Bedingung in meine Abfrage eingefügt werden, wenn es möglich ist?

Danke für Hilfe.

Antwort

0

Es gibt nicht wirklich eine sehr effiziente Möglichkeit, dies zu tun, aber es ist möglich, auch ohne MySQL-Unterstützung für Fensterfunktionen. Es hilft dabei, es einfach zu halten, dass Scores einzelne Ziffern sind und es nur zwei mögliche Scores gibt, die nicht Null sind.

select id_user, 
    3*length(replace(replace(left(group_concat(result order by data desc separator ''), 5), '0', ''), '1', '')) 
     +length(replace(replace(left(group_concat(result order by data desc separator ''), 5), '0', ''), '3', '')) 
     as score_sum 
from my_table 
group by 1 
having count(*) >= 5 
order by 2 desc 
limit 3; 

Brechen es nach unten:

group by 1 Abkürzung für group by id_user (der erste Wert in der select) ist, so dass es nur eine Zeile für jeden Benutzer zurückgeben.

group_concat(result order by data desc separator '') verkettet alle Punkte für einen Benutzer, am allerjüngsten zuerst, ohne Trennzeichen zwischen ihnen hinzugefügt, eine Zeichenfolge wie '033101003' für einen Benutzer produzieren. group_concat wird Daten nach einer bestimmten (konfigurierbaren) Länge abschneiden und eine Warnung erzeugen, aber das ist hier nicht von Bedeutung.

left(..., 5) nimmt die letzten (letzten) fünf Punkte für den Benutzer (z. B. '03310').

replace (..., '0', '') entfernt die 0, also wird das obige Beispiel zu '331'.

Wir zählen, wie viele 3, indem Sie diese Zeichenfolge, ersetzen die 1 mit "" (produzieren "33"), und nehmen Sie die Länge (2).

In ähnlicher Weise zählen wir, wie viele 1, indem Sie diese Zeichenfolge nehmen, ersetzen die 3 mit "" (produzieren "1") und nehmen die Länge (1).

3*...+... die Summe der Noten berechnet, indem der auf die Zahl von 1 3-mal die Anzahl der 3s Zugabe (2 * 3 + 1 in 0,3,3,1,0 eine Summe von 7 für das jeweils fünf letzte Scores ist, 1,0,0,3).

Ich nahm diesen Ansatz, weil es nur zwei nicht-Null-Scores gab, mit denen umzugehen war. Gäbe es mehr, hätte ich einen anderen Zähltrick verwendet. Anstatt die Zahlen zu entfernen, die ich nicht wollte, würde ich diejenigen zählen, die ich gemacht habe. Sie tun dies, indem Sie (length(string)-length(replace(string,searchstring,'')))/length(searchstring) sagen. Beispielsweise. um die cs in abccbacba zu zählen, entfernst du die cs (producing abbaba) und subtrahierst die Länge davon (6) von der Länge der ursprünglichen Zeichenkette (9, erhalte ein Ergebnis von 3).

+0

Hi @ysth es funktioniert perfekt! Aber ehrlich gesagt habe ich die Logik nicht verstanden, mit der Sie diese Abfrage formatiert haben. Ich hoffe, Sie können Schritt für Schritt auf andere Weise erklären. Danke vielmals! –

+0

Ja @ysth, jetzt ist es sehr klar! Vielen Dank für Ihre Unterstützung und Erklärung! –

0

Können Sie versuchen, die SUM (Ergebnis) auf die Unterabfrage zu setzen.

SELECT m1.id_user, m1.data, das Ergebnis als ris FROM my_table m1 join (SELECT ID_USER, SUM (Ergebnis) als Ergebnis FROM my_table GROUP BY ID_USER HAVING COUNT (ID_USER)> = 5) m2 m2 .id_user = m1.id_user GROUP BY id_user ORDER VON m1.data DESC ) ORDER BY ris DESC LIMIT 3;

+0

Hallo @ Jeffrey Hitosis, ich habe versucht, schlagen Sie vor, aber seine Ausgabe berücksichtigt nur die letzten 10 Datensätze eingefügt. –