Pregunta

Tengo un final SELECT loooooooooooong con un ORDER BY que pueden incluir los siguientes valores:

  • comprobado (1 o 0)
  • fecha (AAAA-MM-DD)
  • tiempo (HH: MM: SS)

Me gustaría ordenar el resultado de la consulta de la siguiente manera:

|__checked = 0
|            |__ date ASC
|            |__ time ASC
|            |__ date && time are null  
|__checked = 1
             |__ date ASC
             |__ time ASC
             |__ date && time are null  

Por ahora, tengo algo tan simple como "ORDER BY i1.checked, fecha, hora", pero el problema es con este los artículos con fecha y las horas vacías permanecen en la parte superior.


Aquí está toda la consulta si alguna vez piensa que necesita todos los datos para encontrar una solución adecuada. No gritar.

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

Los elementos se organizan en un árbol con un parent_id y una mesa de cierre.

¿Fue útil?

Solución

ORDER BY il.checked, 
         CASE WHEN date IS NULL AND time IS NULL THEN 1 ELSE 0 END, 
         date, time

Otros consejos

Se puede crear una columna adicional temp en una envuelta seleccione alrededor todo su SQL para permitir que usted agregue un orden artificial.

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top