ORDER BY con bool> Data> nulla a SQLite
-
21-08-2019 - |
Domanda
Ho un finale SELEZIONA loooooooooooong con un ORDER BY che può includere i seguenti valori:
- controllato (1 o 0)
- Data (AAAA-MM-DD)
- ora (HH: MM: SS)
Mi piacerebbe ordinare il risultato della query seguente modo:
|__checked = 0
| |__ date ASC
| |__ time ASC
| |__ date && time are null
|__checked = 1
|__ date ASC
|__ time ASC
|__ date && time are null
Per il momento, ho qualcosa di semplice come "ORDER BY i1.checked, la data, l'ora", ma il problema è con questo le voci con data e tempi di vuoto rimanere sulla parte superiore.
Qui è l'intera query se mai pensi di aver bisogno di tutti i dati per trovare una soluzione adeguata. Non urlare.
SELECT i1._id AS _id, i1.title AS title, i1.checked AS checked,
// count the children (-1 is because the closure table include a relation between any item and itself)
(count( c1.item_id ) - 1) AS children_count,
// count the unchecked children
(SELECT (COUNT(DISTINCT i2._id) )
FROM item AS i2 JOIN closure AS c2 ON (i2._id = c2.item_id)
WHERE c2.ancestor_id = i1._id
AND i2.checked = 0
AND c2.item_id NOT IN (0, i1._id)) AS unchecked_children_count,
// get the closest deadlines among the children :
// if there is a date but no time, time is set to 00:00:00
// if there is a time but not date, date is set to today
// if there is no date nor time, both are set to an empty string
// date
ifnull(nullif((SELECT ifnull(nullif(i3.date, ""), date()) AS subdate
FROM item AS i3 JOIN closure AS c3 ON (i3._id = c3.item_id)
WHERE c3.ancestor_id = i1._id
AND (i3.date OR i3.time)
ORDER By subdate, ifnull(nullif(i3.time, ""), "00:00:00")
LIMIT 1), ""), "") AS date,
// time
ifnull(nullif((SELECT ifnull(nullif(i4.time, ""), "00:00:00") AS subtime
FROM item AS i4 JOIN closure AS c4 ON (i4._id = c4.item_id)
WHERE c4.ancestor_id = i1._id
AND (i4.date OR i4.time)
ORDER By ifnull(nullif(i4.date, ""), date()), subtime
LIMIT 1), ""), "") AS time
FROM item AS i1 JOIN closure AS c1 ON ( i1._id = c1.ancestor_id )
WHERE i1.parent_id = 0
AND c1.item_id != 0
GROUP BY c1.ancestor_id
ORDER BY i1.checked, date, time
Gli elementi sono organizzati in un albero con un parent_id e un tavolo di chiusura.
Soluzione
ORDER BY il.checked,
CASE WHEN date IS NULL AND time IS NULL THEN 1 ELSE 0 END,
date, time
Altri suggerimenti
Si potrebbe creare una colonna aggiuntiva temp
in una avvolto intorno selezionare tutto il vostro SQL per consentire di aggiungere un ordine artificiale.
SELECT
EACH_COLUMN
, ...
, CASE WHEN DATECol IS NULL AND TimeCol is NULL THEN 0
WHEN TimeCol is NULL THEN 1
WHEN DATECol IS NULL THEN 2
ELSE 3 END As ORDERCOL...
FROM
(
INNER MESS OF ALL THE STUFF IN YOUR QUERY
)
ORDER BY
ORDERCol DESC --Preserves order of BothCols Populated, Null Dates Next, Null Times Next, Both Nulls Last
, Checked
, Date
, Time
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow