Sort deadline query chronologically

I don’t understand why… It works

:result-transform (fn [result] 
(sort-by 
  (min (or
    (fn [d] (get d :block/scheduled) ) 
    (fn [d] (get d :block/deadline) ) 
)
  )
 result
)
)

I grabbed a whole bunch of data, but I’m gonna conclude it just doesn’t work.
Using the set up you posted with min and or, it works for scheduled, but deadline doesn’t play nice.


So I went and tried a few different things, but (min …) Seems to not get good results.

… As far as I can tell we need to do this within the confines of a for… But I don’t know how.
I can get (min) to show up properly in a :view component. But not for this (sort-by).

I’ll have to look more at it later, but yeah… :woman_shrugging:t4:
Min across the entire result set vs. Min across the values of one task is the issue here.
Will get back to this. Either with or without an answer.

Ok! I got something to work! The function nesting was wrong. This should work, but please verify with your data! The more different scenarios the better we can see that it works!
We now have a function that returns the minimum value of scheduled and deadline, instead of putting the min straight into the sort-by.

 :result-transform (fn [result] 
  (sort-by 
    (juxt
    (fn [r] (min 
      (get r :block/scheduled 99999999) 
      (get r :block/deadline 99999999) 
    ) )
    (fn [r] (max 
      (get r :block/scheduled 11111111) 
      (get r :block/deadline 11111111) 
    ) )
    )
    result
  )
 )

Here’s a table to see the result a little bit easier. And that seems to show things are in the desired order.

3 Likes

I have not tested this, but should be able to achieve the desired table with this:

:result-transform (fn [result]
  (sort-by
    (fn [r]
      (def d0 (get r :block/deadline))
      (def s0 (get r :block/scheduled))
      (def d (or d0 s0))
      (def s (or s0 d0))
      (+ (max d s) (* 100000000 (min d s)))
    )
    result
  )
)

I literally have that table already, I do not need a query for it. I posted it to show the result transform I posted seems to be working…

Here’s my full query:

#+BEGIN_QUERY
{:title ["📆 near TODOs (scheduled or deadline)"] 
 :query [:find (pull ?b [*])
  :in $ ?start ?next
  :where
          (or
            [?b :block/scheduled ?d]
            [?b :block/deadline ?d]
          )
          [(>= ?d ?start)]
          ;[(<= ?d ?next)]
  ]
 :result-transform (fn [result] 
  (sort-by 
    (juxt
    (fn [r] (min 
      (get r :block/scheduled 99999999) 
      (get r :block/deadline 99999999) 
    ) )
    (fn [r] (max 
      (get r :block/scheduled 11111111) 
      (get r :block/deadline 11111111) 
    ) )
    )
    result
  )
 )
 :view (fn [rows] [:table
   [:thead [:tr   
 [:th "schedule"] [:th "deadline"] 
[:th "min"] [:th "max"]]]
   [:tbody (for [r rows
:let [minus (min (get r :block/scheduled 99999999) (get r :block/deadline 99999999) )]
:let [maximus (max (get r :block/scheduled 11111111) (get r :block/deadline 11111111) )]
]
           [:tr
             [:td (get r :block/scheduled "no value")]
             [:td (get r :block/deadline "no value")]
[:td minus ]
[:td maximus]
           ])
   ]])
  :inputs [:today :7d-after]
:breadcrumb-show? false
  :collapsed? false}
#+END_QUERY

This query works right! Thank you!
Could you help me one more time? I need to embed priority sort. I would like to see the task with A priority above the task without priority. I tried second juxt above yours and i tried put this (fn [b] (get b :block/priority "Z")) as third parameter in your juxt.
`
Screenshot_20230616_122854

It’s because of the max part of my suggestion.
The not priority task has a deadline earlier than the priority task is scheduled.
You can either replace the max part with the line you posted.
Or you can add the line you posted within the same juxt.
Here’s my default task sorting to illustrate:

(juxt
  (fn [r] (get r :block/scheduled 99999999))
  (fn [r] (get r :block/priority "X"))
  (fn [r] (get r :block/deadline 99999999))
  (fn [r] (get r :block/content))
) 

Juxt can have as many lines as needed :slight_smile:

1 Like

It works

 :result-transform (fn [result] 
  (sort-by 
    (juxt
    (fn [r] (min 
      (get r :block/scheduled 99999999) 
      (get r :block/deadline 99999999) 
    ) )
  (fn [r] (get r :block/priority "Z"))
    (fn [r] (max 
      (get r :block/scheduled 11111111) 
      (get r :block/deadline 11111111) 
    ) )
    )
    result
  )
 )
1 Like

Thanks as always for your query expertise. My next 7 query is slightly different because I’m pulling scheduled, deadline, and regular blocks tagged to journal pages. I’m trying to sort it by priority and date. It’s displaying in the opposite direction I’d like, instead of soonest to farthest, it’s going farthest to soonest.

#+BEGIN_QUERY
{:title [:h3 "🗓️ Next 7 days"]
    :query [:find (pull ?h [*])
            :in $ ?next
            :where
            [?h :block/marker ?m]
            [(contains? #{"LATER" "TODO"} ?m)]
            (or-join [?h ?d]
              (and
                [?h :block/ref-pages ?p]
                [?p :block/journal? true]
                [?p :block/journal-day ?d])
              [?h :block/scheduled ?d]
              [?h :block/deadline ?d])
            [(< ?d ?next)]]
  :result-transform (fn [result] 
  (sort-by 
    (juxt
    (fn [r] (min 
      (get r :block/scheduled 99999999) 
      (get r :block/deadline 99999999) 
    ) )
  (fn [r] (get r :block/priority "Z"))
    (fn [r] (max 
      (get r :block/scheduled 11111111) 
      (get r :block/deadline 11111111) 
    ) )
    )
    result
  )
 )
:inputs [:7d-after]
    :collapsed? false}
#+END_QUERY

Sorting seems fine, no?

Not working for me

One way to invert the sorting direction is to reverse the result of the sort like this:

:result-transform (fn [result]
  (reverse
    (sort-by 
      ...
    )
  )
)

Thanks. The issue is that it works if you only use scheduled and deadline. But if you add in journal page references, those sort separately, leaving you with a combined list that’s not sorted properly. I might have to give up on mixing page refs and scheduled/deadline.

Check this out:

#+BEGIN_QUERY
{:title [:h3 "🗓️ Next 7 days"]
    :query [:find ?d (pull ?h [*]  )
:keys date block
            :in $ ?next
            :where
            [?h :block/marker ?m]
            [(contains? #{"LATER" "TODO"} ?m)]
            (or-join [?h ?d]
              (and
                [?h :block/ref-pages ?p]
                [?p :block/journal? true]
                [?p :block/journal-day ?d])
              [?h :block/scheduled ?d]
              [?h :block/deadline ?d])
            [(< ?d ?next)]]
:result-transform (fn [result] 
                    (for [row (sort-by :date result)] 
                      (let [block-map (get row :block)
				               marker (:block/marker block-map)
                              deadline (:block/deadline block-map)
     						  scheduled (:block/scheduled block-map)
                              current-properties (:block/properties block-map)
                              updated-properties (assoc current-properties :date (:date row) :marker marker :scheduled scheduled :deadline deadline)]
                        (assoc block-map
                               :block/properties updated-properties))))
:inputs [:7d-after]
    :collapsed? false}
#+END_QUERY
2 Likes

Brilliant! Thanks so much!

thx for this great query, i use it just for current journal day.
But since “ref-pages” does not work anymore, here the updated example using “path-refs”:

#+BEGIN_QUERY
{:title [:h3 "🗓️ Next 7 days"]
    :query [:find ?d (pull ?h [*]  )
:keys date block
            :in $ ?next
            :where
            [?h :block/marker ?m]
            [(contains? #{"LATER" "TODO"} ?m)]
            (or-join [?h ?d]
              (and
                [?h :block/path-refs ?p]
                [?p :block/journal? true]
                [?p :block/journal-day ?d])
              [?h :block/scheduled ?d]
              [?h :block/deadline ?d])
            [(< ?d ?next)]]
:result-transform (fn [result] 
                    (for [row (sort-by :date result)] 
                      (let [block-map (get row :block)
				               marker (:block/marker block-map)
                              deadline (:block/deadline block-map)
     						  scheduled (:block/scheduled block-map)
                              current-properties (:block/properties block-map)
                              updated-properties (assoc current-properties :date (:date row) :marker marker :scheduled scheduled :deadline deadline)]
                        (assoc block-map
                               :block/properties updated-properties))))
:inputs [:7d-after]
    :collapsed? false}
#+END_QUERY
1 Like