ORDER BY с bool > date > null в SQLite
-
21-08-2019 - |
Вопрос
У меня есть ооооочень длинный SELECT, заканчивающийся ORDER BY, который может включать в себя следующие значения:
- проверено (1 или 0)
- дата (ГГГГ-ММ-ДД)
- время (ЧЧ:ММ:СС)
Я хотел бы упорядочить результат запроса следующим образом:
|__checked = 0
| |__ date ASC
| |__ time ASC
| |__ date && time are null
|__checked = 1
|__ date ASC
|__ time ASC
|__ date && time are null
На данный момент у меня есть что-то простое, например «ORDER BY i1.checked, date, time», но проблема в том, что элементы с пустой датой и временем остаются вверху.
Вот весь запрос, если вы когда-нибудь думали, что вам нужны все данные, чтобы найти правильное решение.Не кричи.
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
Элементы организованы в виде дерева с родительским_идом и закрывающей таблицей.
Решение
ORDER BY il.checked,
CASE WHEN date IS NULL AND time IS NULL THEN 1 ELSE 0 END,
date, time
Другие советы
Вы можете создать дополнительный temp
столбец в обернутом выборе вокруг всего вашего SQL, чтобы вы могли добавить искусственный порядок.
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
Не связан с StackOverflow