1

次の値を含めることができるORDERBYで終わるloooooooooooongSELECTがあります。

  • チェック済み(1または0)
  • 日付(YYYY-MM-DD)
  • 時間(HH:MM:SS)

クエリの結果を次のように並べ替えたいと思います。

|__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とクロージャーテーブルを持つツリーに編成されています。

4

2 に答える 2

7
ORDER BY il.checked, 
         CASE WHEN date IS NULL AND time IS NULL THEN 1 ELSE 0 END, 
         date, time
于 2009-05-11T13:25:52.297 に答える
2

すべてのSQLの周りにラップされた選択で追加のtemp列を作成して、人為的な順序を追加できるようにすることができます。

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
于 2009-05-11T13:25:45.680 に答える