SQL: Erhalte den zweitgrößten Wert aus einer Reihe von Spalten einer Zeile

Ich brauche eine einzige SQL-Abfrage, um den zweitgrößten Wert aus einer Reihe von Spalten einer Zeile zu erhalten. Zum Beispiel, wenn dies die Zeilen meiner Tabelle sind:

id | col1 | col2 | col3 | col4 | coln | 1 | 5 | 7 | 9 | 3 | 10 | 2 | 13 | 14 | 2 | 54 | 11 | 

Für rowid 1 – ich brauche den Wert 9, rowid 2 – ich brauche den Wert 14

Solutions Collecting From Web of "SQL: Erhalte den zweitgrößten Wert aus einer Reihe von Spalten einer Zeile"

Ich fürchte, dass dies ohne gängige Tabellenausdrücke und / oder windowsfunktionen und ohne auf eine Prozedur zu schreiben in MySQL schrecklich ausführlich wird

 SELECT t.id, t.val second_largest -- unpivot your columns into a table FROM ( SELECT id, col1 val FROM my_table UNION ALL SELECT id, col2 FROM my_table UNION ALL SELECT id, col3 FROM my_table UNION ALL SELECT id, col4 FROM my_table UNION ALL SELECT id, coln FROM my_table ) t -- retain only those records, where there exists exactly one record with a -- column value greater than any other column value with the same id WHERE 1 = ( SELECT COUNT(*) -- Here, use unions to be sure that every value appears exactly once FROM ( SELECT id, col1 val FROM my_table UNION SELECT id, col2 FROM my_table UNION SELECT id, col3 FROM my_table UNION SELECT id, col4 FROM my_table UNION SELECT id, coln FROM my_table ) u WHERE t.id = u.id AND t.val < u.val ) 

Hier ist die SQLFiddle , um es zu überprüfen (dank bluefeet für das Heads-up mit dem Schema!). Die obige Lösung findet den zweitgrößten Spaltenwert in jeder Zeile, selbst wenn der größte Spaltenwert mehr als einmal erscheint.

Sie können dies tun, indem Sie die data aufheben und dann eine Zeilennummer auf jeden datasatz in der id Gruppe anwenden. Das Unpivot nimmt die data aus dem Spaltenlayout und platziert sie in Zeilen, so dass es einfacher ist, den zweithöchsten Wert zu bestimmen:

 select id, col, value from ( -- assign a group row number to each record select *, @row:=(case when @prev=id and @prevvalue<>value then @row else 0 end) + 1 as rownum, @prevvalue:=value, @prev:=id pid from ( -- unpivot the multi columns into row values select id, 'col1' col, col1 value from yourtable union all select id, 'col2' col, col2 value from yourtable union all select id, 'col3' col, col3 value from yourtable union all select id, 'col4' col, col4 value from yourtable union all select id, 'coln' col, coln value from yourtable ) src order by id, value desc ) src -- apply filter looking for the rownumber = 2 which is the second highest based on order where rownum = 2 

Siehe SQL Giddle mit Demo

Das Ergebnis wird zeigen:

 | ID | COL | VALUE | --------------------- | 1 | col3 | 9 | | 2 | col2 | 14 | 
 SELECT MAX(col) FROM table WHERE col NOT IN (SELECT MAX(col) FROM table); 

Dies gibt Ihnen den zweitgrößten ganzzahligen Wert in einer bestimmten Spalte.

EDIT: dann vertauschen Sie einfach die Zeilen mit den Spalten, bevor Sie das tun. Aber wenn die Spalten dynamisch sind, könnte es ziemlich schwierig sein.

Der beste / einfachste path wäre, eine Client-Sprache und nicht direkt SQL für diese spezielle Operation zu verwenden. Wenn nicht möglich, aktivieren Sie das Kontrollkästchen: Zeilen und Spalten ohne Aggregat transponieren