2017-07-04 4 views
0

Ich schreibe eine SQL das Medium aus einer Liste von Zahlen zu erhalten (übernehmen die Länge der Liste ungerade ist)order by-Klausel in Mysql

set @r=0; select S.num from (select num, case when num is not NULL then (@r:[email protected]+1) end as rowIndex from T1 order by num) S where rowIndex = ceil(@r/2) Diese Abfrage funktioniert, aber ich bin verwirrt durch meine subquery . Meine Frage ist die folgende: Wenn ich einfach gebe, habe ich 2 Spalten, wobei die erste Spalte die ursprüngliche Liste von Zahlen in der ursprünglichen Reihenfolge ist, z. B. 10,1,3,11,5,4,19. und die zweite Spalte ist der Zeilenindex, 1,2,3,4, .... Beachten Sie, dass ich zuerst meine ursprüngliche Liste in aufsteigender Reihenfolge sortieren und dann jeder Zeile ihren Zeilenindex geben soll.

Ich dachte zunächst, dass select num, case when num is not NULL then (@r:[email protected]+1) end as rowIndex from T1 order by num eine Tabelle zu produzieren, so dass die erste Spalte die sortierte Version meiner ursprünglichen Liste ist, aber dann der 2. Säule ist eine Umlagerung des Indexmenge [1,2,3, ... ]. Weil ich denke, die Reihenfolge der Abfrage ist: zuerst erstellen Sie eine Tabelle wie von select num, case when num is not NULL then (@r:[email protected]+1) end as rowIndex from T1 vorgeschlagen, dann sortiert es diese Tabelle von num Spalte, und daher, wenn num Spalte sortiert ist, sollte die rowIndex Spalte nicht mehr sein [1,2,3 , ...].

Aber eigentlich scheint es, dass es zunächst nur die num Spalte sortieren und dann Zeilenindex hinzufügen. In einem anderen Wort finde ich, dass, ob ich order by num hinzufüge oder nicht, die 2. Spalte immer ein schöner Zeilenindex [1,2,3,4, ...] sein wird. Warum?

+0

Können Sie ein tabellarisches Daten Beispiel hinzufügen, weil es jetzt wirklich schwer zu folgen, was Sie sprechen –

+0

@NorbertvanNobelen Sorry, ich war gerade dabei zu tun, @Used_By_Already hat eine Tabelle in der Antwort unten gemacht. Aber ich bin immer noch verwirrt über diese 'order by' -Klausel in Mysql – ftxx

Antwort

1

Die abgeleitete Tabelle (Unterabfrage) sortiert Ihre num Spalte und gibt jeder Zeile eine Indexnummer gemäß dieser Reihenfolge. Die äußere Abfrage verwendet dann das berechnete Vale von @r erneut, um den halben Weg (Median) in dieser geordneten Reihe zu erreichen.

CREATE TABLE mytable(
    num NUMERIC(6,2) 
); 
INSERT INTO mytable(num) VALUES (12.4); 
INSERT INTO mytable(num) VALUES (134.9); 
INSERT INTO mytable(num) VALUES (45.12); 
INSERT INTO mytable(num) VALUES (876.78); 
INSERT INTO mytable(num) VALUES (212.8); 
INSERT INTO mytable(num) VALUES (578.9); 
set @r=0; 
select num, case when num is not NULL then (@r:[email protected]+1) end as rowIndex 
from mytable T1 
order by num; 
 
    num | rowIndex 
-----: | -------: 
12.40 |  1 
45.12 |  2 
134.90 |  3 
212.80 |  4 
578.90 |  5 
876.78 |  6 
set @r=0; 
select S.num 
from (
    select num, case when num is not NULL then (@r:[email protected]+1) end as rowIndex 
    from mytable T1 
    order by num 
    ) S 
where rowIndex = ceil(@r/2); 
 
| num | 
| -----: | 
| 134.90 | 

dbfiddle here

Wenn wir den Auftrag durch jedoch die Ergebnisse zu entfernen sind nicht vorhersehbar. z.B.

set @r=0; 
select num, case when num is not NULL then (@r:[email protected]+1) end as rowIndex 
from mytable T1 
; 
 
    num | rowIndex 
-----: | -------: 
12.40 |  1 
134.90 |  2 
45.12 |  3 
876.78 |  4 
212.80 |  5 
578.90 |  6 
set @r=0; 
select S.num 
from (
    select num, case when num is not NULL then (@r:[email protected]+1) end as rowIndex 
    from mytable T1 
    ) S 
where rowIndex = ceil(@r/2); 
 
| num | 
| ----: | 
| 45.12 | 

dbfiddle here

Ohne explizite ORDER BY-Klausel ist es NICHT sicher anzunehmen, dass die Nummernreihen so geordnet werden, wie Sie sie benötigen. Es kann vorkommen, aber Sie können sich nicht darauf verlassen.

+0

Danke! Aber was mich wirklich verwirrt macht, ist, dass ich 'Select Num, @r: = @ r + 1 end als rowIndex von mytable T1 order by num 'für die zweite Spalte' 1,3,2,5,6,4' halte '. Aber es gibt "1,2,3,4,5,6". Ich meine, wenn Sie nur 'num ausführen, @r: = @ r + 1 end als rowIndex von mytable T1', dh ohne' order by num', wäre die zweite Spalte der Ausgabe immer noch '1,2, 3,4,5,6 'richtig ?, dann halte ich eine zusätzliche' Ordnung von 'ist eine Operation auf der abgeleiteten Tabelle, so sollte nicht die zweite Spalte' 1,2,3,4,5,6 'auch sein geordnet nach der Reihenfolge der 'num' Spalte? – ftxx

+0

* "würde mir die 2. Spalte 1,3,2,5,6,4 geben." * Nein, würde es nicht. Wäre dies der Fall, wäre es völlig unbrauchbar, in der Mitte zu arbeiten. Die Verwendung dieser Variablen wird von der Reihenfolge nach beeinflusst. - Gott sei Dank. –

+0

Ich weiß, aber ich frage mich, die Reihenfolge der Generierung neuer Tabellen in SQL. Also sollte 'Select num, @r: = @ r + 1 end als rowIndex from mytable' eine Tabelle mit 2 Spalten erzeugen und so dass die erste Spalte eine unsortierte Liste von Zahlen ist und die zweite Spalte '1,2,3, 4,5,6 'richtig? Dann nenne ich diese Tabelle "T2", sollte es im Speicher gespeichert werden, oder? Dann sollte die Operation 'order by num' die Zeilen der Tabelle' T2' neu anordnen, oder? Warum hat diese Umlagerung dann keinen Einfluss auf die zweite Spalte in "T2"? – ftxx