2017-03-21 1 views
0

Verzeihen Sie mir, wenn dies jemand anderes beantwortet; Ich habe eine Arbeitstabelle, die ich in MySQL über eine Abfrage neu anordnen möchte. Der Arbeitstisch sieht wie folgt aus:Rekonfigurieren Sie Tabellenspalte Daten in Zeilen über SQL-Abfrage

 
+-------+------+-------+ 
| Sport |Points| Name | 
+-------+------+-------+ 
| A  | 53 | Alex | 
| A  | 22 | Jim | 
| A  | 11 | Josh | 
| B  | 63 | Joe | 
| B  | 22 | Rich | 
| B  | 10 | Frank | 
+-------+------+-------+ 

Ich bin für eine effiziente Art und Weise zur Ausgabe der Tabelle in diesem Format durch eine SQL-Abfrage suchen:

+-------+-----+---------+-----+---------+-----+---------+ 
| Sport | 1st | 1stName | 2nd | 2ndName | 3rd | 3rdName | 
+-------+-----+---------+-----+---------+-----+---------+ 
| A  | 53 | Alex | 22 | Jim  | 11 | Josh | 
| B  | 63 | Joe  | 22 | Rich | 10 | Frank | 
+-------+-----+---------+-----+---------+-----+---------+ 

Normalerweise würde ich nicht meine Tabelle formatiert wird auf diese Weise , aber es macht es einfacher für mich, die Top 3 Spieler pro Sport per PHP anzuzeigen. Jede effiziente Vorschläge sind absolut willkommen. Vielen Dank!

+0

Ich empfehle Ihnen, die Zeilen nur mit 'ORDER BY Sport, Punkte DESC' zu holen und sie dann mit PHP-Code in Spalten anzuordnen. Das wird einfacher sein. –

Antwort

1

Berechnen Sie zuerst die Zeilennummern anhand einer Variablen, die auf der absteigenden Reihenfolge der Punkte für jede Sportart basiert.

Verwenden Sie dann bedingte Aggregation, um die besten 3 Ergebnisse pro Sport in einer Reihe zu erhalten.

select sport 
,max(case when rnum=1 then points end) as p_1 
,max(case when rnum=1 then name end) as n_1 
,max(case when rnum=2 then points end) as p_2 
,max(case when rnum=2 then name end) as n_2 
,max(case when rnum=3 then points end) as p_3 
,max(case when rnum=3 then name end) as n_3 
from (
select sport,points,name 
,@rn:=case when [email protected]_sport then @rn+1 else 1 end as rnum 
,@prev_sport:=sport 
from t 
join (select @rn:=1,@prev_sport:='') r 
order by sport,points desc 
) x 
group by sport 

Im Falle von Verbindungen in Punkten, wird ein Name willkürlich aufgenommen.

Um die Bindungen aufzuheben, um den niedrigsten oder höchsten Namen anzuzeigen, kann die obige Abfrage leicht geändert werden, um eine Bestellung für Name zu enthalten.

select sport 
,max(case when rnum=1 then points end) as p_1 
,max(case when rnum=1 then name end) as n_1 
,max(case when rnum=2 then points end) as p_2 
,max(case when rnum=2 then name end) as n_2 
,max(case when rnum=3 then points end) as p_3 
,max(case when rnum=3 then name end) as n_3 
from (
select sport,points,name 
,@rn:=case when [email protected]_sport then @rn+1 else 1 end as rnum 
,@prev_sport:=sport 
from t 
join (select @rn:=1,@prev_sport:='') r 
order by sport,points desc,name --change it to name desc if the highest name should be shown in case of ties 
) x 
group by sport 
+0

Das ist eine großartige Antwort und hat fantastisch funktioniert; es wurde viel schneller verarbeitet als jede der Lösungen, die ich versuchte. Ich scheue mich vor benutzerdefinierten Variablen, weil sie nicht mit Ansichten in MySQL arbeiten, aber ich fange an, die Wichtigkeit von ihnen zu sehen und versuche, meinen Arbeitsstil zu ändern, um sie öfter zu integrieren. Nochmals vielen Dank! –

Verwandte Themen