2012-09-30 17 views
5

Chcesz sortować puste jednostki i puste miejsca i przeczytać wszystkie rozwiązania, które używają funkcji Coalesce lub If w porządku według kolumny.Sortowanie wartości Null ostatnie

MOJE problemy nie dotyczą tych zadań, ponieważ kolumna, którą sortuję jest określana dynamicznie przez skrypt PHP, który tworzy zapytanie, a niektóre z moich kolumn znajdują się w dwóch tabelach w moim sprzężeniu.

$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"; 

to działa świetnie, mogę zmienić zmiennej $ sortcol i moja aukcja wyjście działa świetnie z wyjątkiem wartości null i wykroje są na górze.

podstawie innych księgowań Próbowałem to

$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"; 

ta zgłasza błąd „kolumny łodzi w klauzuli ORDER BY jest niejednoznaczne”. Oczywiście, że chce b.boat w kolejności, ale z powodów, do których nie wejdę, jest problematyczne. Wygląda na to, że w każdej chwili próbuję użyć funkcji w klauzuli orderby Nie mogę użyć aliasu kolumny.

Jakieś pomysły na eleganckie rozwiązanie tego?

Odpowiedz

4

Masz rację. Bez żadnego powodu, który mogę zgłębić, MySQL akceptuje niejednoznaczne ORDER BY tak długo, jak podane przez ciebie nazwisko nie jest traktowane w żaden sposób (nie ma mowy, żebym mógł myśleć o. Może inni istnieją).

Tak szybko, jak to jest, niejednoznaczność zostaje odrzucona.

ta jest akceptowana (i zbędne):

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

podczas COALESCE(name, ''), name IS NULL, name OR NULL są odrzucane.

Oczywistym rozwiązaniem jest użycie innej nazwy dla aliasu, takiej, która nie pojawia się w żadnej z tabel.

Kolejną możliwością byłoby utworzyć zagnieżdżony zapytanie:

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

czyli:

$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

Ciekawe mówisz, że jeśli używam b.boat jak boatname zamiast b.boat jako łódź będzie działać ??? – davewhirlwind

+0

Tak, dokładnie. O ile nie masz innego pola o nazwie 'boatname' :-) – LSerni

+0

To działało dzięki. – davewhirlwind

1

Musisz określić tabelę w ORDER BY, jeśli masz dwie podobne nazwy kolumn. To takie proste.

Powinieneś być w stanie użyć innego aliasu w SELECT który disambiguates z obu boat kolumn, a następnie użyć jej w

$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"; 

Uwaga: jeśli $sortcol jest wynikiem jakichkolwiek danych wprowadzonych przez użytkownika, to jest konieczne, aby porównać go z białą listą dopuszczalnych nazw kolumn, aby zapobiec iniekcji SQL.

1

z kolumny aliasach ANSI SQL, stosowanych w klauzuli ORDER BY może być stosowany tylko przez siebie - nie można używać aliasów do rzutowania innych kolumn lub wyrażeń.

Więc kiedy name stosowany jest w porządku przez liście i nie jest wyrazem jest interpretowane jako odniesienie do aliasu. Po użyciu w wyrażeniu, nie może rozwiązać aliasu, dlatego MySQL próbuje znaleźć kolumnę, która to rozwiąże. W zapytaniu znajdują się dwie takie kolumny w zakresie, stąd błąd dotyczący niejednoznaczności.

Takie zachowanie rozdzielczości można zobaczyć na poniższym (testowane w MySQL i 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 

Powroty (zamówione przez alias)

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

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

Powroty (zamówione przez kolumnę bazowej)

D   C 
----------- ----------- 
2   1 
1   2 
Powiązane problemy