'How to group results per month since there is operator for month?

When I query and step using make-series I can choose to step by hour (1h) day (1d) but how do I handle when I want the step to be per month? (1m) seems to be per minute

My query looks like this

let _timePeriodInHours = abs(datetime_diff('hour', _startTime, _endTime));
let _stepConfig = case(_timePeriodInHours <= 24, timespan(1h), _timePeriodInHours <= 744, timespan(1d), timespan(30d));
tilldevicedata
| where todatetime(TransactionTimeStampUtc) between (_startTime.._endTime)
| where Brand has_any (_brand)
| where Country == _country
| where Store has_any (_store)
| make-series TotalDiscounts = sum(TransactionValueDiscount), TotalSales = sum(TransactionValueNet) default = 0 on todatetime(TransactionTimeStampUtc) step _stepConfig

The idea is to have the graph per month if user selects more than 31 days apart in the dateTime Selector but it seems not easily possible, it works fine for hour and day but as soon as I pass 744 hours in the _timePeriodInHours variable the stepCOnfig becomes 30d whcih is not really correct for month and it also looks weird ause it ends up with the graph showing a Time instead of a month

How can I handle the grouping per month when user selects over 744h and stepConfig should be 1M = 1 month?

----- EDIT -----

Almost there

LAST 24 HOURS

This works fine given the solution below, see how the hours are looking normal as in 18:00 19:00 etc

Last 24 h

LAST 14 Days Using Last 14 days this also looks good note the month etc is nicely spread

last 14d

Now here comes the weird parts, if I select last 12 hours, notice how the time is not shown nicely any longer as 18:00 it adds milliseconds etc and looks totally weird

LAST 12h last 12h

And the weirdest of them all is last 60 days which looks totally absurd with just a weird timestamp ?

LAST 60d enter image description here

Currently query looks like this

let _timePeriod = _endTime - _startTime;
let _stepConfig = case(_timePeriod <= 24h, 1h, 1d);
tilldevicedata
| extend dttm = todatetime(TransactionTimeStampUtc)
| where dttm between (_startTime.._endTime)
| where Brand has_any (_brand)
| where Country == _country
| where Store has_any (_store)
| make-series TotalDiscounts = sum(TransactionValueDiscount) default = 0, TotalSales = sum(TransactionValueNet) default = 0 on dttm = case(_timePeriod <= 744h, dttm, startofmonth(dttm)) step _stepConfig
| mv-apply TotalDiscounts, TotalSales, dttm to typeof(datetime) on (where _timePeriod <= 744h or dttm == startofmonth(dttm) 
| summarize make_list(TotalSales), make_list(dttm))
| render timechart


Solution 1:[1]

There is no "month" timespan, so some tricks are required here.
While this can be solved pretty easily by using summarize instead of make-series, by doing that we lose a main advantage of make-series, which is the gap filling of missing data.
Therefore, here is a solution based on make-series.

The main trick here is to use make-series with 1d step for the monthly report, for a data that was already grouped by month (this is achieved by using make-series ... on ... startofmonth(dttm)...), and after that keeping the data only for the 1st of every month.

// Generation of a data sample. Not part of the solution.
let tilldevicedata = materialize(range i from 1 to 1000000 step 1 | extend dttm = ago(365d*rand()) | where dttm !between (ago(5h) .. 3h) and dttm !between (ago(7d) .. 3d));
// The solution starts here.
let _startTime = ago(600d);
let _endTime = now();
let _timePeriod = _endTime - _startTime;
let _stepConfig = case(_timePeriod <= 24h, 1h, 1d);
tilldevicedata
| make-series count() on dttm = case(_timePeriod <= 744h, dttm, startofmonth(dttm)) from bin(_startTime, _stepConfig) to _endTime step _stepConfig
| mv-apply count_, dttm to typeof(datetime) on (where _timePeriod <= 744h or dttm == startofmonth(dttm) | summarize make_list(count_), make_list(dttm))
| render timechart

Fiddle

Monthly

_startTime = ago(600d)

Monthly

Daily

_startTime = ago(15d)

Daily

Hourly

_startTime = ago(21h)

Hourly

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1