2010-01-12 6 views
7

nur eine Frage ziemlich ähnlich wie diese gefragt ...MySQL orderby eine Reihe, Leer Strings (oder 0en) Last

Zur Zeit mache ich eine sehr grundlegende SortiertNach in meiner Aussage.

SELECT * FROM tablename WHERE visible=1 ORDER BY position ASC, id DESC 

Das Problem dabei ist, dass leere Zeichenfolge Einträge für ‚Position‘ als 0. Daher alle Einträge mit Position behandelt, als leere Zeichenfolge vor denen mit 1,2,3,4 erscheinen. Beispiel:

'', '', '', 1, 2, 3, 4

oder

0, 0, 0, 1, 2, 3, 4

Gibt es eine Möglichkeit, die folgende Bestellung zu erreichen:

1, 2, 3, 4, '', '', ''.

oder

1, 2, 3, 4, 0, 0, 0

Ich nehme die Lösung eine Art Funktion ersetzen kann, aber ich habe nicht in der Lage gewesen, eine Funktion zu finden, die tut was ich suche, durch google.

Vielen Dank,

JonB

Antwort

15
SELECT * 
FROM tablename 
WHERE visible=1 
ORDER BY 
    case when position in('', '0') then 1 else 0 end, 
    position ASC, 
    id DESC 
+1

Ich denke, das wird funktionieren, aber es ist nicht die beste Lösung. Ich denke, "position" sollte eine Integer-Spalte sein, und wenn das der Fall ist, sollte der CASE-Ausdruck auch ganze Zahlen verwenden, keine Strings. Wenn "Position" keine Ganzzahl oder zumindest numerisch ist, funktioniert das Sortieren nach Zahlen nicht. Außerdem fügt diese Lösung eine neue Spalte hinzu, nach der sortiert werden kann, was sich wahrscheinlich negativ auf die Leistung auswirkt.Wenn meine Annahme, dass "position" tatsächlich eine Ganzzahl ist, korrekt ist, dann bedeutet der OP wahrscheinlich "NULL" -Wert, wo er 'leere Zeichenfolge' geschrieben hat, was bedeutet, dass Sie einfach 'ORDER BY COALESCE (Position, ~ 0), ID DESC' schreiben können –

+0

@Roland: Das OP impliziert ziemlich klar, dass die Position eine Zeichenkette ist: * "Das Problem dabei ist, dass leere Zeichenketteneinträge für 'Position' wie 0 behandelt werden." * – RedFilter

+0

OrbMan ja, er tat es. Und ich sage, dass das wahrscheinlich ein Teil des Problems ist. Mein Vorschlag war, es vorne einen richtigen Dateityp zu geben, anstatt zu versuchen, danach zu wischen. –

0

Sie können die Verbindung von zwei Unterabfragen versuchen, wo eine select id> 0 und nicht leer und die andere wählen leer und 0 nur

1

Sie könnten versuchen, ein CASE statement, wie folgt aus:

SELECT * 
FROM tablename 
WHERE visible = 1 
ORDER BY CASE position WHEN '' THEN '9999' ELSE position END CASE ASC, 
    ID DESC 
+0

Ich weiß, dies ist eine alte Antwort, aber es ist nur meinen Hintern gerettet. Danke, Mann! – mingos

1

Sie sagen, dass position enthält leere String-Einträge ... Meinst du wirklich leere Zeichenfolge, oder meinst du NULL? Wenn es NULL Einträge tatsächlich enthält, sollten Sie eine leichte Modifikation von Orbman Aussage verwenden:

SELECT * 
FROM tablename 
WHERE visible=1 
ORDER BY 
    COALESCE(position, ~0) 
, id DESC 

COALESCE() gibt den Wert des ersten Arguments, das NOT NULL ist. Die ~ 0 ist ein Stück schwarzer Magie, das Ihnen den von MySQL unterstützten maximalen Integer-Wert liefert. (~ macht eine bitweise Negation, alle 0 Bits werden zu 1). Wenn also in diesem Fall position IS NULL wahr ist, wird 18446744073709551615 zurückgegeben, andernfalls wird der Wert position zurückgegeben.

Ich möchte auch darauf hinweisen, dass der Datentyp Ihrer position Spalte höchstwahrscheinlich von einem ganzzahligen Typ sein sollte (siehe http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html). Da Sie leere Zeichenfolgen erwähnen, sollten Sie Ihre Tabellendefinition überprüfen, indem Sie SHOW CREATE TABLE <tablename> ausführen. Wenn Position kein Integer-Typ ist, würde ich Ihnen raten, es zu ändern. Der Hauptgrund ist, dass Strings, auch wenn sie wie Zahlen aussehen, nicht als Zahlen sortiert werden.