ORDER BY с помощью bool> date> null в SQLite - PullRequest
1 голос
/ 11 мая 2009

У меня есть loooooooooooong 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

Элементы организованы в дерево с parent_id и таблицей закрытия.

Ответы [ 2 ]

6 голосов
/ 11 мая 2009
ORDER BY il.checked, 
         CASE WHEN date IS NULL AND time IS NULL THEN 1 ELSE 0 END, 
         date, time
2 голосов
/ 11 мая 2009

Вы можете создать дополнительный столбец 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
...