[SQL] "Gejointe" Tabelle nach zwei Spalten sortieren

Hallo,

da mir derzeit die Ideen ausgegangen sind, frage ich hier nach ob mein Vorhaben überhaupt mit SQL zu lösen wäre oder ob ich es dann zwangsweise über PHP lösen müsste.

Folgende Tabellenkonstruktion:

Ich habe eine Tabelle namens “parteien”, als Beispiel habe ich mir folgendes rausgesucht.

Die Tabelle “matches” beinhaltet noch andere Daten, welche für das Problem nicht relevant sind, die Tabelle “namen” enthält die ID, welcher unter Sportler zu finden ist, sowie als Spalte “name” den jew. Vor- & Nachnamen des Sportlers.

Die “gejointe” Tabelle sieht dann erstmal wie folgt aus:

Mein Ziel ist es nun, da die Namen innerhalb der einzelnen Parteien durcheinander sind, diese innerhalb der Parteien nach dem Alphabet zu ordnen.
Dieses Vorhaben ist ja auch kein Problem.

Was jedoch nicht funktioniert ist folgendes: Anschließend möchte ich, dass die Ausgabe nach dem Alphabet sortiert ausgegeben wird, unabhängig von der Partei.
D.h. sollte ein Sportler mit dem Vornamen “A…” in Partei 3 sein, so müsste dieser als Erstes ausgegeben werden, dann bspw. “B…” aus Partei 2 etc.

Im oben gegebenen Beispiel wäre die richtige Reihenfolge daher:

So einfach funktioniert es jedoch nicht mit ORDER BY partei, name, da nicht zwingend jemand mit A in Partei 1 sein muss etc.

Ich hoffe das Problem ist einigermaßen verständlich & irgendjemand kann mir einen entscheidenen Tip geben - vielen Dank! :slight_smile:

Das sortiert zuerst nach `partei` und dann nach `name`.

Dein Beispiel Ergebnis ist genau das, was ich erwarten würde.

Zeig doch mal bitte den gesamten Query (evt auf die relevanten Felder beschränken), inklusive ORDER BY und dem Ergebnis und erkläre was dir daran nicht passt

Das sortiert zuerst nach partei und dann nach name.

Dein Beispiel Ergebnis ist genau das, was ich erwarten würde.

Zeig doch mal bitte den gesamten Query (evt auf die relevanten Felder beschränken), inklusive ORDER BY und dem Ergebnis und erkläre was dir daran nicht passt

Der gesamte Query ist der aus dem Bild der “gejointen” Tabelle + halt die Order-Klausel.

Aber hier ein anderes Beispiel, welches mein Problem vlt. ein bisschen besser visiualisiert.

Die Sortierung innerhalb der einzelnen Parteien ist wunderbar so, keine Frage (soweit war dies ja auch kein Problem für mich ^^).
Nun besteht jedoch das Problem, dass primär nach der Partei sortiert wird & wie man in diesem Beispiel sieht, gibt es in Partei #2 jemanden, der im Alphabet zuerst kommt, bevor der Erste in Partei #1.
Dementsprechend müsste in diesem Fall die Reihenfolge der Parteien geändert werden, so dass C, D, M - J, M, R ausgegeben wird.

Für dieses Problem habe ich leider keine Lösung. :slight_smile:

dann sortier doch erst nach name, dann nach partei?

Damit mache ich dann jedoch die Sortierung der Parteien kaputt.

Dieses Vorhaben ist mir natürlich auch bereits in den Sinn gekommen, aber verfehlt ja leider die Korrektheit.

Mein derzeitiges PHP-Skript orientiert sich anhand der Parteien ob Partner sind oder Gegner & man daran das “&” oder das “vs.” fest.
Anhand der nun vorhandenen Tabelle wäre das Resultat verfälscht.

Wenn mein Vorhaben via SQL nicht lösbar ist, dann muss ich mir halt etwas Anderes einfallen lassen dies via Skript zu lösen. ^^

Du möchtest die Parteien Gruppiert haben, aber es soll die Partei als erstes haben, die den alphabetisch “niedrigsten” Namen hat?

Du könntest das möglicherweise mit einem Subquery in den Feldern erreichen, und dort nach MIN(name) sortieren.

Um das mal ganz grob zusammen zu fassen (hab grad keine Zeit)

Da ein Name allerdings durchaus per zufall in mehreren Parteien sein kann (menschen mit dem gleichen Namen gibt es ja), müsste man das auch berücksichtigen.

Magst du vielleicht mal erklären, warum du die in dieser besonderen Sortierung haben möchtest?

mfg
Balmung

Genau.

Der Code klingt ja an sich relativ vernünftig, magst Du da ggf. noch 1-2 Erklärungen zu abgeben?! :slight_smile:

Weshalb diese besondere Reihenfolge?
Naja, so besonders ist die ja eig. nicht.
Ich bin derzeit dabei meine Tabellen zu normalisieren & habe mich dafür entschieden, dass die Ausgabe am Ende für die Leser halt alphabetisch sortiert sein sollte.

Sollte es dazu kommen, dass tatsächlich zwei den gleichen Namen tragen, joar, aber das wäre wohl zu viel Aufwand.
Dies habe ich aber bei den tausenden von Einträgen bis dato noch nicht festgestellt. ^^

Die Idee ist es ein weiteres Feld, nach der man sortieren kann, hinzuzufügen. Dieses Feld enthält dann für jede Partei immer den “niedrigsten” Namen, unabhängig davon wie der Name des aktuellen Datensatzes ist:

(ich hab die irrelevanten felder mal weggelassen)

+--------+-------------------+--------------+
| partei | name              | sortfield    |
+--------+-------------------+--------------+
| 2      | CIMA              | CIMA         |
| 2      | Dragon Kid        | CIMA         |
| 1      | Jimmy Susumu      | Jimmy Susumu |
| 2      | Masaaki Mochizuki | CIMA         |
| 1      | Mr. Quu Quu Naoki | Jimmy Susumu |
| 1      | Ryo "Jimmy" Saito | Jimmy Susumu |
+--------+-------------------+--------------+

Hier könnte man dann effektiv nach “sortfield” sortieren, partei “2” landet also oben, und danach noch, wenn man möchte, nach “name” sortieren.

Das ganze macht man mit einem Subquery zwischen SELECT und FROM. Dieser Subquery muss ein Skalar, also einen einzigen Wert und einen einzigen Datensatz, zurückgeben.
Dieser Subquery muss wahrscheinlich auch einen JOIN beinhalten, damit du auf die Namen zugreifen kannst.

So oder so ähnlich. Das musst du noch an deine Bedürfnisse anpassen, da ich nicht ganz durchgeblickt habe, wie bei dir die Relationen sind:

SELECT
    ...,
    (SELECT
         MIN(local_namen.name)
     FROM local_parteien
     JOIN local_namen
     ON local_parteien.sportler = local_namen.id
     WHERE local_parteien.id = parteien.id
    ) AS sortfield
FROM matches
JOIN parteien
...
ORDER BY sortfield, name

Die innere Klammerung ist der Subquery. Mit der WHERE Clause gehe ich sicher, dass nur eine Partei zurückgegeben wird. und da ein JOIN stattfindet, könnten mehrere Namen zurückkommen. Von diesen Namen wähle ich den “niedrigsten” mit MIN() aus.

Ich hoffe das war jetzt etwas einleuchtender

mfg
Balmung

Edit: achso, wie performant das ganze ist weiß ich nicht. Da sollte man vllt mal ein EXPLAIN oder ANALYZE oder so drüber laufen lassen (kA wie der genaue Begriff bei MySQL lautet)

Ich hab’s mal grad in meiner PostgreSQL Konsole ausprobiert :smiley:

allgemeine-zone.net/quote/q/2T0VlFWzZH

Ich glaube aber, ich hab andere Relationen genutzt (da ich nicht wirklich weiß wie sie bei dir genau aufgebaut sind).