• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

ORDER BY mit CASE

Status
Für weitere Antworten geschlossen.
Hallo,

ich habe eine Ausgabe mehrere Ergebnisse, die primär nach der festgelegten Reihenfolge der Disziplinen sortiert werden. Bei gleichen Disziplinen möchte ich so sortieren lassen, dass die besten werte oben stehen, also bei Laufdisziplinen der kleinste Wert, bei Sprungdisziplinen und Wurfdisziplinen der größte Wert...

Meine Abfrage sieht bis jetzt so aus:
PHP:
SELECT  DISTINCT  * 
FROM ergebnisse
JOIN athleten ON ergebnisse.skuerzel = athleten.skuerzel
JOIN athleten1 ON ergebnisse.skuerzel1 = athleten1.skuerzel1
JOIN athleten2 ON ergebnisse.skuerzel2 = athleten2.skuerzel2
JOIN athleten3 ON ergebnisse.skuerzel3 = athleten3.skuerzel3
JOIN athleten4 ON ergebnisse.skuerzel4 = athleten4.skuerzel4
JOIN disziplinen ON ergebnisse.dkuerzel = disziplinen.dkuerzel
JOIN altersklassen ON ergebnisse.akuerzel = altersklassen.akuerzel
WHERE ergebnisse.akuerzel =  'mju20'
AND jahr =12
ORDER  BY disziplinen.reihenfolge, ergebnis ASC

Nun bekomme ich alle Ergebnisse der Männlichen Jugend U20 aus dem Jahr 2012 in der gewünschten Reihenfolge der Disziplinen geliefert. Bei den Laufdisziplinen klappt auch die aufsteigende Sortierung der Ergebnisse bei mehreren Ergebnissen in der gleichen Disziplin.
Allerdings werden natürlich auch die Sprung/Wurf-Ergebnisse aufsteigend sortiert, was ich aber genau andersherum haben möchte.

Nun gibt es ja eine CASE Anweisung, die man - soweit ich weiß - theoretisch auch in dem ORDER BY Teil nutzen kann. Da alle Ergebnisse der Wurf/Sprung Disziplinen auf ein "m" enden (für Meter), habe ich mir folgendes überlegt:

PHP:
ORDER BY 
CASE WHEN 'ergebnis'!='' THEN 'disziplinen.reihenfolge ASC'
WHEN 'ergebnis'!='%m' THEN 'ergebnis ASC'
WHEN ergebnis= '%m' THEN 'ergebnis DESC' END

Theoretisch dachte ich so erreichen zu können, dass er immer die Reihenfolge beachtet, die in der Tabelle disziplinen abgelegt sind, und dann prüft ob am Ende ein m oder halt kein m vorkommt...
Aber sortiert ist in der Ausgabe nichts, weder nach der Reihenfolge, noch nach irgendwelchen Ergebnisendungen...

Wie kann ich also beschreiben, dass er immer nach der festgelegten Reihenfolge sortiert und dann noch nach dem Parameter m oder kein m? (Und dann jeweils die Sortierrichtung umdreht)
 
Werbung:
Ist das MySQL oder Oracle?

Vorschlag:
Schreib die Bedingung ins SELECT, also

Code:
CASE WHEN 'ergebnis'!='' THEN 'disziplinen.reihenfolge ASC'
WHEN 'ergebnis'!='%m' THEN 'ergebnis ASC'
WHEN ergebnis= '%m' THEN 'ergebnis DESC' END as orderby

und verweise unten beim Sortieren auf diese Ergebnisspalte:

Code:
ORDER BY orderby

Ggfs. musst Du auch noch die Sortierspalte (z.B. disziplinen.reihenfolge) von der Sortierreihenfolge (z.B. ASC) trennen und mit 2 Spalten arbeiten.

Bin mir sicher, dass das bei Oracle funktionieren sollte. Bei MySQL bin ich mir nicht sicher.
 
Werbung:
Bei MySQL kenn ich CASE bisher nur von Funktionen? Bei normalen Statements gibts doch IF?
 
Ja, das habe ich auch gerade in einem Beitrag von vor 12 Jahren gelesen... Aber die Anwendung an sich läuft dann nach einem ähnlichen Schema ab und müsste dann auch direkt bei dem ORDER BY funktionieren?

Edit:
Hier habe ich einen Beitrag gefunden, der fast das gleiche Problem behandelt, allerdings wird da zweimal in die gleiche Richtung sortiert, aber es wird mit if gelöst. Allerdings habe ich die Syntax der if-Anweisung noch nicht ganz begriffen, aber mal sehen...
 
Zuletzt bearbeitet:
Habe es so hinbekommen:
PHP:
ORDER BY 
CASE
WHEN ergebnis NOT LIKE '' THEN disziplinen.reihenfolge END ASC,
CASE WHEN ergebnis NOT LIKE '%m' THEN ergebnis END ASC,
CASE WHEN ergebnis LIKE'%m' THEN ergebnis END DESC
Nicht schön, aber selten. Vielen Dank trotzdem für deine Hilfe, threadi!
 
Werbung:
So, habe nun noch eine andere Frage: Das Ergebnis sieht bei mir jetzt so aus:

100 m10,00 sec.Name192Berlin
100 m10,45 sec.Name292München
100 m10,67 sec.Name392Hamburg
400 m55,21 sec.Name192München
400 m56,32 sec.Name392Berlin

Jetzt würde ich gerne noch erreichen, dass die Disziplin nur einmal je Abfrage angezeigt wird. Aussehen soll es am Ende also so:

100 m10,00 sec.Name192Berlin
10,45 sec.Name292München
10,67 sec.Name392Hamburg
400 m55,21 sec.Name192München
56,32 sec.Name392Berlin

Jetzt meine Frage:
Ist das mit mysql in Verbindung mit PHP möglich? Meine Abfrage sieht wie folgt aus:

PHP:
<?php
require_once ('config-statistik.php');
$sql = "SELECT * FROM ergebnisse
JOIN athleten ON ergebnisse.skuerzel = athleten.skuerzel
JOIN athleten1 ON ergebnisse.skuerzel1 = athleten1.skuerzel1
JOIN athleten2 ON ergebnisse.skuerzel2 = athleten2.skuerzel2
JOIN athleten3 ON ergebnisse.skuerzel3 = athleten3.skuerzel3
JOIN athleten4 ON ergebnisse.skuerzel4 = athleten4.skuerzel4
JOIN disziplinen ON ergebnisse.dkuerzel= disziplinen.dkuerzel
JOIN altersklassen ON ergebnisse.akuerzel = altersklassen.akuerzel
WHERE ergebnisse.akuerzel='mju20'
AND jahr=12
ORDER BY
CASE
WHEN ergebnis NOT LIKE '' THEN disziplinen.reihenfolge END ASC,
CASE WHEN ergebnis NOT LIKE '%m' THEN ergebnis END ASC,
CASE WHEN ergebnis LIKE'%m' THEN ergebnis END DESC";
$db_erg = mysql_query( $sql );
if ( ! $db_erg )
{
die('Ungültige Abfrage: ' . mysql_error());
}
echo '<table border="1">';
while ($zeile = mysql_fetch_array( $db_erg, MYSQL_ASSOC))
{
echo "<tr>";
echo "<td>". $zeile['disziplin'] . "</td>";
echo "<td>". $zeile['ergebnis'] . "</td>";
echo "<td>". $zeile['athlet']; 
if($zeile['athlet4'] != ''){
    echo "<br />". $zeile['athlet1'];
    echo "<br />". $zeile['athlet2'];
    echo "<br />". $zeile['athlet3'];
    echo "<br />". $zeile['athlet4'];
}elseif($zeile['athlet3'] != ''){
    echo "<br />". $zeile['athlet1'];
    echo "<br />". $zeile['athlet2'];
    echo "<br />". $zeile['athlet3'];
}elseif($zeile['athlet2'] != ''){
    echo "<br />". $zeile['athlet1'];
    echo "<br />". $zeile['athlet2'];
}
echo "</td>";
echo "<td>";
if($zeile['athlet2'] == ''){
    echo $zeile['jahrgang'];
}
echo"</td>";
echo "<td>".$zeile['ort'].", " .$zeile['tag'].".".$zeile['monat'] . "</td>";

echo "</tr>";
}
echo "</table>";
mysql_free_result( $db_erg );

?>
 
Stimmt
das wird sonst viel zu kompliziert

PHP:
if  ($wert == X) {ORDER BY ......}
if  ($wert == Ý) {ORDER BY ......}
if  ($wert == Z) {ORDER BY ......}

oder mit case
 
Werbung:
@Tomm,
verstehe den Bezug zu meiner aktuellen Fragen nicht.

@Threadi,
Könntest du mir da ein oder zwei Stichworte geben, nach denen ich suchen muss? Leider weiß ich nicht, wie ich die MySql Augabe soweit mit PHP beeinflussen kann.
 
Du willst doch nur in bestimmten Zellen in bestimmten Momenten keine Ausgabe haben. Also:

PHP:
if( bedingung ) { echo "<td>". $zeile['disziplin'] . "</td>"; }else { echo "<td></td>"; }

Und die Bedingung musst Du nur noch so definieren, dass sie nur zutrifft, wenn bei 2 aufeinanderfolgenden Zellen die Werte sich geändert haben.
 
... Stimmt, danke für den Schubs in die richtige Richtung. Werde mir das morgen näher anschauen, auch was die Überprüfung auf gleiche Werte hintereinander angeht.
 
Werbung:
So, bin nun wieder an dem Problem dran und habe mal Google bemüht um zu begreifen, wie ich die Inhalte der Spalte "disziplin" so überprüfen kann, dass ich nachher nur den ersten Wert der jeweiligen Disziplin ausgeben kann....

Aber so richtig weit bin ich nicht gekommen. Ich habe den Gedanken im Kopf ob es möglich und praktisch wäre, die gleichen Einträge zu zählen und dann jeweils nur in der Zeile auszugeben, wo die Zählvariable "1" beträgt.
Allerdings komme ich nicht weiter, wie ich das anstellen kann und ob das überhaupt der beste und effizienteste Weg ist.

Zählen an sich ist ja mit der sql-Funktion count möglich. Wenn ich mir diese Frage hier anschaue: [MySQL] identische Einträge zählen
Dann habe ich da ja schonmal die Anzahl der Disziplinen die mehrfach vorkommen. Aber hilft mir sowas weiter? Wie könnte ich die Daten dann weiterverarbeiten? Oder gibt's einen ganz anderen Weg?
 
Werbung:
Das ist doch nur ein logisches Konstrukt, das muss man nicht unbedingt ergoogeln.

Beispiel:
PHP:
$wertalt = "";
while( $row = mysql_fetch_array($result) ) {
 if( $wertalt != $row['feld' ] ) {
  echo "unterschiedlicher wert der ausgegeben wird<br />";
 }
 $wertalt = $row['feld'];
 echo "hier dann noch weitere ausgaben<br />";
}
 
Hallo,

ich habe jetzt ein (hoffentlich letztes) Problem entdeckt...

Wenn beispielsweise beim Kugelstoßen ein paar Ergebnisse über 10 m liegen, und einige nur 9 m gestoßen haben, wird das in der Tabelle wie folgt dargestellt:

Kugelstoßen 5 kg8,11 m
7,91 m
13,31 m
11,13 m

Ihr seht sicher, wo das Problem liegt. Er sortiert nach der ersten Zahl und dann erst nach der zweiten, weshalb alle Ergebnisse über 10 m unter den Ergebnissen gelistet werden, die unter 10 m liegen...

Mein Code sieht so aus:

PHP:
<?php
 require_once ('config-statistik.php');
 $sql = "SELECT DISTINCT * FROM ergebnisse
 JOIN athleten ON ergebnisse.skuerzel = athleten.skuerzel
 JOIN athleten1 ON ergebnisse.skuerzel1 = athleten1.skuerzel1
 JOIN athleten2 ON ergebnisse.skuerzel2 = athleten2.skuerzel2
 JOIN athleten3 ON ergebnisse.skuerzel3 = athleten3.skuerzel3
 JOIN athleten4 ON ergebnisse.skuerzel4 = athleten4.skuerzel4
 JOIN disziplinen ON ergebnisse.dkuerzel= disziplinen.dkuerzel
 JOIN altersklassen ON ergebnisse.akuerzel = altersklassen.akuerzel
 WHERE ergebnisse.akuerzel='m'
 AND jahr=12
 ORDER BY
 CASE
 WHEN ergebnis NOT LIKE '' THEN disziplinen.reihenfolge END ASC,
 CASE WHEN ergebnis LIKE '%m' THEN ergebnis END DESC,
 CASE WHEN ergebnis LIKE '%sec%' THEN ergebnis END ASC,
 CASE WHEN ergebnis LIKE '%min%' THEN ergebnis END ASC,
 CASE WHEN ergebnis LIKE '%Std%' THEN ergebnis END ASC,
 CASE WHEN ergebnis LIKE '%Pkt%' THEN ergebnis END DESC";
 $db_erg = mysql_query( $sql );
 if ( ! $db_erg )
 {
 die('Ungültige Abfrage: ' . mysql_error());
 }
 echo '<table>';
 $wertalt = "";
 while ($zeile = mysql_fetch_array( $db_erg, MYSQL_ASSOC))
 {
 echo "<tr>";
 if( $wertalt != $zeile['disziplin' ] ) {
   echo "<td>". $zeile['disziplin'] . "</td>";
  }
  else{
     echo"<td></td>";
  }
$wertalt = $zeile['disziplin'];
 echo "<td>". $zeile['ergebnis'] . "</td>";
 echo "<td>". $zeile['athlet'];
 if($zeile['athlet4'] != ''){
     echo "<br />". $zeile['athlet1'];
     echo "<br />". $zeile['athlet2'];
     echo "<br />". $zeile['athlet3'];
     echo "<br />". $zeile['athlet4'];
 }elseif($zeile['athlet3'] != ''){
     echo "<br />". $zeile['athlet1'];
     echo "<br />". $zeile['athlet2'];
     echo "<br />". $zeile['athlet3'];
 }elseif($zeile['athlet2'] != ''){
     echo "<br />". $zeile['athlet1'];
     echo "<br />". $zeile['athlet2'];
 }
 echo "</td>";
 echo "<td>";
 if($zeile['athlet2'] == ''){
     echo $zeile['jahrgang'];
 }
 echo"</td>";
 echo "<td>".$zeile['ort'].", " .$zeile['tag'].".".$zeile['monat'] . "</td>";
 echo "</tr>";
 }
 echo "</table>";
 mysql_free_result( $db_erg );
?>

Der wichtigste Teil dürfte ja die CASE-Anweisungen sein.
Wie kann ich erreichen, dass bei der Sortierung die ganze Zahl vor dem Komma berücksichtigt wird? Muss ich dazu in der CASE Anweisung die Fälle beschreiben, dass zwei oder nur eine Zahl vor dem Komma steht, oder wie könnte das möglich sein?

Vielen Dank schonmal.
 
Werbung:
Moin,
du hast das Datenbakfeld mit den Ergebnissen in einem varchar oder textfeld kann das sein?
Dann lässt sich an der Sortierung nicht viel machen, weil es keine Zahlen sind.

evtl. könntest du das feld bei der abfrage nach DECIMAL oder SIGNED(Integer) CASTEN(umwandeln) und danach sortieren dabei gehen aber sicher die Nachstellen flöten.
Beispiel:
Code:
SELECT DISTINCT *, CAST(`ergebnis` AS DECIMAL) AS ergebnis_int FROM ergebnisse
.......
CASE WHEN ergebnis LIKE '%m' THEN ergebnis_int END DESC,
......
Vielleicht hilft das ein wenig.

Deswegen sollte man Zahlenwerte auch immer als solche in die DB eintragen und ein zusätzliches feld für den wertetyp (m,km,std...).

MfG
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben