2012-09-30 12 views
5

Sie möchten Nullen und Leerzeichen zuletzt sortieren und alle Lösungen gelesen haben, die entweder die Coalesce-Funktion oder die If-Spalte in der Reihenfolge verwenden.Sortieren von Nullen zuletzt

Meine Probleme sind nicht von diesen Arbeiten für mich, weil die Spalte, die ich sortiere, dynamisch vom PHP-Skript angegeben wird, das die Abfrage erstellt, und einige meiner Spalten sind in zwei Tabellen in meinem Join.

$sortcol="boat"; 
    $sql= "SELECT fleet,b.boat as boat,owner FROM boats as b 
    LEFT JOIN owners as o ON b.boat=o.boat 
    ORDER BY $sortcol"; 

Dies funktioniert gut, kann ich die Variable $ sortcol und Auflistung meiner Ausgabe funktioniert mit Ausnahme der nulls groß ändern und Zuschnitte an der Spitze sind.

Basierend auf anderen Postings habe ich versucht, diese

$sortcol="boat"; 
    $sql= "SELECT fleet,b.boat as boat,owner FROM boats as b 
    LEFT JOIN owners as o ON b.boat=o.boat 
    ORDER BY IF($sortcol is NULL,1,0), $sortcol"; 

Diese den Fehler wirft "-Spalte Boot in ORDER BY-Klausel ist nicht eindeutig". Offensichtlich will b.boat in der Reihenfolge nach, aber aus Gründen, die ich nicht eingehen werde, ist das problematisch. Es scheint, dass ich jederzeit, wenn ich versuche, eine Funktion in der orderby-Klausel zu verwenden, den Spaltenalias nicht verwenden kann.

Irgendwelche Ideen für eine elegante Lösung?

Antwort

4

Sie haben Recht. Aus keinem Grund, dass ich ergründen kann, akzeptiert eine mehrdeutige ORDER BY so lange wie der Name, den Sie liefern, in keiner Weise behandelt wird (keine Möglichkeit, dass ich denken könnte. Vielleicht gibt es andere).

Sobald es ist, wird Mehrdeutigkeit abgelehnt.

Dies wird angenommen (und redundant):

select b.id, a.name as name 
    FROM client AS a JOIN client AS b ON (a.id = b.id) 
    ORDER BY name, name; 

während COALESCE(name, ''), name IS NULL, name OR NULL alle abgelehnt.

Die offensichtliche Lösung besteht darin, für den Alias ​​einen anderen Namen zu verwenden, der in keiner der beiden Tabellen erscheint.

Eine weitere Möglichkeit, eine verschachtelte Abfrage zu erstellen wäre:

SELECT * FROM (your query here, without ORDER) AS original 
ORDER BY IF($sortcol is NULL,1,0), $sortcol; 

Das heißt:

$sortcol="boat"; 
$sql = <<<SQL 
    SELECT * FROM (
     SELECT fleet,b.boat as boat,owner FROM boats as b 
     LEFT JOIN owners as o ON b.boat=o.boat 
    ) AS original 
    ORDER BY IF($sortcol is NULL,1,0), $sortcol; 
SQL; 
+0

Interessante sagen Sie, dass, wenn ich b.boat als boatname statt b.boat als Boot verwenden wird es funktionieren ??? – davewhirlwind

+0

Ja, genau. Es sei denn, Sie haben ein anderes Feld namens boatname :-) – LSerni

+0

Das hat funktioniert. – davewhirlwind

1

Sie müssen die Tabelle in der ORDER BY angeben, wenn Sie zwei ähnliche Spaltennamen haben. So einfach ist das.

Sie sollten einen anderen Alias ​​in der SELECT nutzen können, die von beiden boat Spalten disambiguiert und verwenden Sie dann, dass in der

$sortcol = "bboat"; 
$sql= " 
    SELECT 
    fleet, 
    /* Alias as bboat to disambiguate from b.boat and o.boat 
    b.boat as bboat, 
    owner 
    FROM 
    boats as b 
    LEFT JOIN owners as o ON b.boat=o.boat 
    ORDER BY IF($sortcol is NULL,1,0), $sortcol"; 

Hinweis: Wenn $sortcol ist das Ergebnis von jeder Art von Benutzereingaben es, ist notwendig, um es mit einer Whitelist von akzeptablen Spaltennamen zu vergleichen, um SQL-Injection zu verhindern.

1

Nach ANSI SQL-Spalte Aliase, wenn in der ORDER BY Klausel verwendet wird, kann nur durch sich selbst verwendet werden - Sie können die Aliase nicht zum Projizieren anderer Spalten oder Ausdrücke verwenden.

Also, wenn name in der Reihenfolge von Liste verwendet wird und nicht in einem Ausdruck ist, wird es als eine Referenz auf den Alias ​​interpretiert. Sobald es in einem Ausdruck verwendet wird, kann es nicht zu einem Alias ​​aufgelöst werden, so dass MySQL versucht, eine Spalte zu finden, um dies zu lösen. Es gibt zwei solche Spalten im Umfang in Ihrer Abfrage, daher der Fehler, den Sie über Mehrdeutigkeit erhalten.

Diese Auflösung Verhalten aus den folgenden (getestet in MySQL und SQL Server)

CREATE TABLE T 
(
C INT, 
D INT 
) 

INSERT INTO T 
SELECT 1, 2 UNION ALL 
SELECT 2, 1 

SELECT C AS D, D AS C 
FROM T 
ORDER BY D 

Returns (geordnet nach Alias)

D   C 
----------- ----------- 
1   2 
2   1 

SELECT C AS D, D AS C 
FROM T 
ORDER BY D + 0 
zu sehen

Returns (von Basisspalte geordnet)

D   C 
----------- ----------- 
2   1 
1   2 
Verwandte Themen