Ho una tabella di oggetti PostgreSQL con un campo di ordinazione facoltativo:
CREATE TABLE tasks ( id integer PRIMARY KEY DEFAULT nextval('f_seq'), f_id integer REFERENCES fixins, name text NOT NULL, sort integer );
Voglio le attività che non hanno alcun valore di ordinamento da ordinare dopo tutte le altre, con un’eccezione: se sort = -1
voglio che venga ordinata dopo quelle. Quindi, ad esempio, dati questi valori:
id | f_id | name | sort ---+------+----------+------- 1 | 1 | zeta | -1 2 | 1 | alpha | 1 3 | 1 | gamma | 3 4 | 1 | beta | 2 5 | 1 | delta | 6 | 1 | epsilon |
Li voglio ordinare come: alpha
, beta
, gamma
, delta
, epsilon
, zeta
.
So che posso usare ORDER BY COALESCE(sort,99999)
per ordinare valori nulli dopo valori non nulli, ma come posso ottenere quel valore -1
speciale che verrà dopo quelli?
Più semplice:
SELECT * FROM tasks ORDER BY (sort IS NOT DISTINCT FROM -1), sort;
Postgres ha un tipo boolean
appropriato (a differenza di altri RDBMS). È ansible ordinare da esso proprio come qualsiasi altro tipo di dati. E può essere NULL come qualsiasi altro tipo di dati. L’ordinamento predefinito è:
FALSE (0) TRUE (1) NULL
(sort IS NOT DISTINCT FROM -1)
valuta FALSE
per tutti i valori tranne -1
– che valuta TRUE
e ordina per ultimo. Basta aggiungere l’ sort
come articolo ORDER BY
secondario.
Alternativa equivalente
SELECT * FROM tasks ORDER BY (sort IS DISTINCT FROM -1) DESC, sort;
SQL Fiddle.
SELECT name FROM tasks WHERE f_id=1 ORDER BY CASE COALESCE(sort,88888) WHEN -1 THEN 99999 ELSE COALESCE(sort,88888) END, id;
Ancora alla ricerca di un modo più elegante di farlo solo una volta, senza selezionarlo.