Werte innerhalb einer Abfrage weiterverwenden

Doofi

Benutzer
Beiträge
9
Hallo Forum, ich steh auf dem Schlauch!
Folgende SQL-Abfrage habe ich:
SELECT NAME, MAX(WERT) AS MAXSCORE, SUM(WERT) AS SUMME, COUNT(WERT) AS ANZ,
SUM(CASE WHEN r1 = 0 THEN 1 ELSE 0 END +
CASE WHEN r2 = 0 THEN 1 ELSE 0 END +
CASE WHEN r3 = 0 THEN 1 ELSE 0 END +
CASE WHEN r4 = 0 THEN 1 ELSE 0 END +
CASE WHEN r5 = 0 THEN 1 ELSE 0 END +
CASE WHEN r6 = 0 THEN 1 ELSE 0 END +
CASE WHEN r7 = 0 THEN 1 ELSE 0 END +
CASE WHEN r8 = 0 THEN 1 ELSE 0 END +
CASE WHEN r9 = 0 THEN 1 ELSE 0 END +
CASE WHEN r10 = 0 THEN 1 ELSE 0 END +
CASE WHEN r11 = 0 THEN 1 ELSE 0 END +
CASE WHEN r12 = 0 THEN 1 ELSE 0 END +
CASE WHEN r13 = 0 THEN 1 ELSE 0 END +
CASE WHEN r14 = 0 THEN 1 ELSE 0 END +
CASE WHEN r15 = 0 THEN 1 ELSE 0 END +
CASE WHEN r16 = 0 THEN 1 ELSE 0 END +
CASE WHEN r17 = 0 THEN 1 ELSE 0 END +
CASE WHEN r18 = 0 THEN 1 ELSE 0 END +
CASE WHEN r19 = 0 THEN 1 ELSE 0 END +
CASE WHEN r20 = 0 THEN 1 ELSE 0 END
) AS AnzNull FROM challenge WHERE UEBUNG='Route 64' GROUP BY NAME ORDER BY MAXSCORE DESC;

Die Daten werden derzeit über die Spalte MAXSCORE sortiert. Da hier die Werte aber häufig gleich sind, benötige ich ein 2. Kriterium. Das soll aus den Spalten R1 bis R20 kommen. Dort möchte ich die vorhanden Felder mit 0 als Wert zählen ,das funktioniert auch. Ich brauche das Ergebnis davon (Also den Inhalt von AnzNull) als weitere Sortieroption. Um den zu verwenden, muss AnzNull noch durch die den Wert aus ANZ geteilt werden und das Ergebnis daraus kann ich als weitere Sortieroption nutzen.
Ich hoffe man kann verstehen, was gemeint ist. Ich bräuchte jetzt also ein AnzNull / ANZ = NullErgebnis, das würde dann am Ende des Select mit sortiert, also quasi
ORDER BY MAXSCORE, NullErgebnis DESC;
Geht sowas in einem Statement oder muss ich das über PHP regeln?
 
Werbung:
benötigst du womöglich distinct?
womöglich auch einen subselect?

Ich blicke bei deinem Schreiben absolut garnicht durch, ....

Was möchtest du via die Datenbank erfassen?
Erzähl ein bisschen mehr Hintergrundinformationen ;)

LG Kampfgummibaerlie
 
Hallo, ja, hab ich mir schon gedacht 🙈 dass das ein bisschen wirr ist. Ich fang noch mal an:
Ich habe folgende Abfrage:
SELECT
NAME,
MAX(WERT) AS MAXSCORE,
SUM(WERT) AS SUMME,
COUNT(WERT) AS ANZ
FROM challenge WHERE UEBUNG='Sweet 16' GROUP BY NAME ORDER BY MAXSCORE DESC;
Das erzeugt bspw ein Ergebnis wie folgt :
PLATZNAMEPUNKTESCHNITT
[td width="20.2587%"]
1​
[/td][td width="25.6465%"]
Maverick​
[/td][td]
90​
[/td][td]
1 / 90​
[/td]​
Die Tabelle sieht wie folgt aus:
1761342025075.webp
Da es vorkommen kann, dass in der Spalte WERT gleiche Werte stehen, brauche ich noch ein weiteres Sortierargument: Das soll der Anteil der Einträge bei R1 bis R20 mit 0 sein (im ersten Beitrag hab ich das schon drin, das wäre dann AnzNull), im Verhältnis zu den Versuchen. Also pro NAME für die Einträge mit 0 die Summe bilden, und diese dann möglichst durch die Anzahl der Versuche zählen (in der Abfrage schon vorhanden als ANZ).
Das ist auch meine Frage, ob ich das Ergebnis der Zählung der 0-Einträge (im ersten Beitrag schon drin) verwenden kann, um dann die Ausgabe bei Gleichheit von WERT nach der Berechnung der 0-Einträge geteilt durch ANZ sortieren zu lassen.
Ich hoffe, das ist jetzt ein bisschen erkennbarer, was ich möchte. Kurz gesagt: haben 2 Personen den gleichen WERT erspielt, entscheidet über die Platzierung, wer die wenigsten Einträge mit 0 in seinen Übungen hat. Das ganze ist eine Trainings-challenge für Dartspieler
LG Micha
 
Konkret zu Deiner Frage, Du kannst innerhalb einer Abfrage einen neue erzeugten Wert nicht ohne weiteres weiterverwenden.
(Es gibt glaub ich DB, die das in gewisser Weiße können, mysql z.B., kenne ich aber nicht gut genug und Deine Abfrage an sich scheint mir problematisch genug, also lasse ich das offen)

Du kannst z.B. ganz einfach SQL Abfragen verschachteln, Beispiel
select c, d from
(select a, b, c, a+b as d from meineTabelle ) s
where s.a > 5

Du kannst auch WITH CTE verwenden.

Was mich an Deiner Frage irritiert ist der Aufbau der "Tabelle" und Stichwörter wie "Übung".
Wer übt hier was? Baust Du eine Übung? Oder folgst Du einer?

Ohne weiter ins Detail zu gehen, die Tabelle mit den 20 R Spalten sieht fürchterlich aus und sollte nicht als Übung verwendet werden. Zumindest nicht als Material für Anfänger (weil Übung).
Falls das nur ein "anonymisiertes" Beispiel für ein Realworldproblem ist, was Du in Deiner Firma hast, dann erkläre bitte mehr zu der Bedeutung dieser Tabelle und ihren Spalten. Angefangen damit: Ist es überhaupt eine Tabelle oder nur ein Artefakt aus einem Verarbeitungsprozess wo die Originaldaten ganz anders strukturiert sind. Ist die Tabelle vielleicht eigentlich eine Abfrage(View) oder das Ergebnis einer Abfrage in eine Tabelle überführt?
 
Danke erstmal für eure Bemühungen. Ich bin leider auch nicht so der Profi was Datenbankanwendungen angeht, aber ich versuch hier mal zu beschreiben, was das ganze für einen Hintergrund hat.
Es ist eine PHP-Anwendung für ein Dart-Trainingsprogramm. Das Frontend sieht so aus:
1761388186010.webp
Die Werte werden nach Abschluss in eine Mysql-Db geschrieben, für verschiedene Spieler, und jede Woche gibt es eine neue Übung.
1761388329833.webp Es gibt für jede Übung immer ein Ranking, wer die meisten Punkte erreicht hat (Für jeden Spieler der beste Versuch (Spalte WERT) für eine Übung.
Die Spalten R1 bis R20 enthalten das Ergebnis für eine Runde, der Spieler hat 20 Runden innerhalb der Übung zu absolvieren. Da es möglich ist, dass mehrere Spieler ein gleiches Ergebnis erzielen (Spalte WERT) muss für ein Ranking noch ein 2. Kriterium herangezogen werden.
Das soll sich aus den Spalten R1 bis R20 ergeben, nämlich die Anzahl der 0-Werte in den Spalten für jeden Versuch, den der Spieler unternommen hat, dividiert durch die Anzahl der Versuche. Hat Spieler A z.B. 3x die Übung abgeschlossen, 100 Punkte an WERT erspielt und bei jedem Versuch 5x 0-Werte erzielt (in den Spalten R1-R20) hat er insgesamt 15x 0-Werte. Diese durch 3 Versuche dividiert ergeben einen Schnitt von 5 0-Werten je Übung. Spieler B hat auch 100 Punkte WERT erspielt, hat aber nur 1 Versuch unternommen und dabei nur 3x 0-Werte, würde das ergeben 3 dividiert durch 1 = Schnitt von 3, er wäre im Ranking also vor Spieler A platziert.

Und genau das ist mein Problem. Ich benötige also irgendwie folgende Daten in der Abfrage:
Name des Spielers: NAME
Bestes Ergebnis des Spielers: MAX(WERT) AS MAXSCORE
Anzahl der Versuche je Übung: COUNT(WERT) AS ANZ
Anzahl der 0-Einträge:
SUM(CASE WHEN r1 = 0 THEN 1 ELSE 0 END +
CASE WHEN r2 = 0 THEN 1 ELSE 0 END +
CASE WHEN r3 = 0 THEN 1 ELSE 0 END +
CASE WHEN r4 = 0 THEN 1 ELSE 0 END +
CASE WHEN r5 = 0 THEN 1 ELSE 0 END +
CASE WHEN r6 = 0 THEN 1 ELSE 0 END +
CASE WHEN r7 = 0 THEN 1 ELSE 0 END +
CASE WHEN r8 = 0 THEN 1 ELSE 0 END +
CASE WHEN r9 = 0 THEN 1 ELSE 0 END +
CASE WHEN r10 = 0 THEN 1 ELSE 0 END +
CASE WHEN r11 = 0 THEN 1 ELSE 0 END +
CASE WHEN r12 = 0 THEN 1 ELSE 0 END +
CASE WHEN r13 = 0 THEN 1 ELSE 0 END +
CASE WHEN r14 = 0 THEN 1 ELSE 0 END +
CASE WHEN r15 = 0 THEN 1 ELSE 0 END +
CASE WHEN r16 = 0 THEN 1 ELSE 0 END +
CASE WHEN r17 = 0 THEN 1 ELSE 0 END +
CASE WHEN r18 = 0 THEN 1 ELSE 0 END +
CASE WHEN r19 = 0 THEN 1 ELSE 0 END +
CASE WHEN r20 = 0 THEN 1 ELSE 0 END
) AS AnzNull
Durchschnitt der 0-Einträge pro Runde: AnzNull dividiert durch ANZ

Und das ganze alles in einem SQL-Statement, dass ich absetzen kann. Ich habe soweit schon alles gelöst, mir fehlt nur noch der letzte Teil, wie ich in der Abfrage das Ergebnis ANZ durch AnzNull dividieren und den Wert dann in der Ausgabe nutzen kann.
Sollte das nicht machbar sein, ist das nicht tragisch, dann müsste ich eben ein 2. SQL Statement erstellen und das dann unter PHP erledigen, ich hatte nur gehofft, man könnte das eventuell im sql direkt unterbringen.

Das war jetzt viel getippe, aber so ausführlich wie möglich.

lg Micha
 
OK, also ein Missverständnis, es geht nicht um Üben von SQL, sondern darum diese bestehende, vorgegebene Tabelle auszuwerten.
Nimm doch einfach wie vorgeschlagen ein verschachteltes SQL und mach damit weiter.
 
Schön sind die ganzen R-Spalten natürlich nicht und die negativen Konsequenzen des Designs sind jetzt "spürbar". Manchmal ist das aber zweckdienlich, da muss man jetzt nicht gleich alles umbauen.

Grundsätzlich solltest du ein Aggregat auch im ORDER BY verwenden können, würde ich jetzt annehmen. Also kannst du theoretisch auch das ganze SUM(CASE ...) im ORDER BY ein zweites mal auflisten. Du kannst das leicht testen in dem du ORDER BY MAX(WERT) DESC anstelle von ORDER BY MAXSCORE DESC verwendest. In MSSQL kann man die Spalte im ORDER BY auch mit einer Nummer angeben, also ORDER BY 2 DESC , das wird aber in MySQL eventuell nicht gehen. (Und auch das ist nicht empfehlenswert für produktiven Code, genau wie SELECT * .)
 
Werbung:
Danje für den Hinweis, werde ich mal probieren. Ich weiss auch, dass die Struktur der DB nicht sonderlich schön ist, habe aber keine elegantere Lösung für den Zweck gefunden.
 
Zurück
Oben