How can I calculate my total number of the complete tasks in the specific period?

Hi, I’m a newbie in the dataview and obsidian. After using the tasks plugin, it’s easy to use. But now I want to know how to get the number of completed tasks in the specific period (for example, between yesterday and today) by the dataview or other ways. I suppose it’s an easy question but cannot find the answer. Does anyone have a suggestion?

Things I have tried

I’ve checked the dataview’s document but didn’t find ways to implement it.

1 Like

Hi @sfffaaa. Would done after yesterday accomplish what you’re after?
[Edit: It might need to be done after 2 days ago. I don’t use Tasks so I’m not sure if it’s inclusive or exclusive of the date you mention.]

Hi, thanks for your reply, but sorry for confusing you. I am stuck on how I write the query to get the total number of completed tasks. For example, when I use

due after 2023-01-04

It returns the list of tasks, but I only want the total number instead of the list of tasks.

Is Nicole van der Hoeven’s example of COUNT useful?

The last example on Dataviewjs - Fork My Brain

Count number of results returned

This returns notes of type: session whose filenames start with 2022:

table length(rows) as Number from "TTRPGs"
where contains(type,"session") and contains(file.name,"2022")
group by type

I see two main hurdles to get what you want:

  • Translate the Tasks icons into something usable by dataview
  • Translating your tasks query into a table query, where you can do a group and list the length of all rows, aka the count of tasks

Translating tasks icon

I was here thinking that I might need to catch the icon, do some regex, and then finally extract the date from the text of the task. Doable, but cumbersome. Luckly the guys doing Dataview has done this for the most useful stuff, so they’ve got the following covered:

Field name Short hand syntax
due :spiral_calendar:YYYY-MM-DD
completion :white_check_mark:YYYY-MM-DD
created :heavy_plus_sign:YYYY-MM-DD
start :flight_departure:YYYY-MM-DD
scheduled :hourglass_flowing_sand:YYYY-MM-DD

Nice, that makes this a little easier, let’s do the table query then.

TABLE query instead of tasks query

In order to be able to do a table query, we need to FLATTEN the tasks of a file into each and every task there is. This can be rather expensive if done on an entire vault. So any limitations like doing FROM "journal" or FROM #taskFiles or similar, is advantageous for the total query.

So you stated the query due after 2023-01-04, which would be something similar to due > date("2023-01-04"), which in a full query would look like:

```dataview
TABLE WITHOUT ID length(rows), T.text, T.due
WHERE this.file.name = file.name
FLATTEN file.tasks as T
WHERE T.due > date("2023-01-04")
```

NB! I’m using the WHERE this.file.name = file.name to limit my test to only the current file for test purposes. You change this to something suiting your needs (or remove it and run against the entire vault)

In order to get a count out of this, there are two ways to do so, we could “simply” add GROUP BY true to it, and do length(rows) within an ordinary query, or we could switch to a dataviewjs query, and just return the number of elements in the result.

Example with GROUP BY true
```dataview
TABLE WITHOUT ID length(rows) as count, rows.T.text, rows.T.due
WHERE this.file.name = file.name
FLATTEN file.tasks as T
WHERE T.due > date("2023-01-04")
GROUP BY true
```

Here I’ve also added some descriptive text, and joined up the text and due dates. The downside with this approach is that the count is not very useful for anything, and can’t really be repurposed, but it shows the gist of the idea.

Example with dataviewjs and length of list

I imagine you want to output this in a sentence some where, and then an inline dataviewjs query would be more suited for the task. We’re still building out of the same query as before, but we now add some stuff around it to get better handling and possibilities to present the result.

```dataviewjs
const taskQuery = await dv.query(`\
  TABLE WITHOUT ID T.text, T.due
  WHERE this.file.name = file.name
  FLATTEN file.tasks as T
  WHERE T.due > date("2023-01-04")
`)

// console.log(taskQuery)
if ( taskQuery.successful ) {
  dv.span(`Found ${ taskQuery.value.values.length } tasks`)
} else
  dv.paragraph("~~~~\n" + taskQuery.error + "\n~~~~")
```

In my case, this returns:
![image|186x53](upload://bhEhW69DZoVVnGmI9p4vLrRrJKK.png)


In summary, you’ll need to first find the DQL query, like the query above, which shows the tasks you want to count, and then you need to insert them into an inline dataviewjs query, like in the last example, and adapt the text to your liking, and that should give you the task count you’re wanting.

Note that you don’t really need to “understand” that dataviewjs query, just copy your working query into it, and the result should pop out just fine. (If you want the output within a paragraph, you might want to change from ```dataviewjs … ``` into `$= … `, but that does also require some changes to the script (like including semicolons here and there… )

3 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.