Counting the number of breakdown elements that match a certain criteria

graycarper
Giga Guru

Hello there!

Let's say we have a formula indicator called "% Incident Awesomeness" and it has a breakdown on Business Service. Let's say we then wanted to create a new formula indicator that counts the number of Business Services whose % Incident Awesomeness is greater than 60%.

For example: Business Service Unicorn has 99% Incident Awesomeness, Business Service Rainbow has 80% Incident Awesomeness, and Business Service Hurricane has  2% Incident Awesomeness. In this scenario, the new formula indicator would record a count of 2, since two of those are greater than 60%.

How would you go about defining that formula indicator?

In my imaginary world, I thought perhaps a script like this might work...

var count = 0;
for (var element in [[% Incident Awesomeness > Business Service]]) {
  if (element > 60) {
    count = count + 1;
  }
}
count;

...but apparently you can't iterate through Breakdowns using the '>' notation.

Any other ideas out there?

Thank you!

-Gray

1 ACCEPTED SOLUTION

Josh Cooper
ServiceNow Employee
ServiceNow Employee

Neat question!

So, I'm not sure if there's a quicker way to do this, but here's a method that will work.

 

Build a new Indicator Source against any table, but filter the results so that you get exactly one result.  Something like sys_user where User is graycarper, or Incident where Incident Number is INC0001001, etc.  The table doesn't matter as long as the result is one

Then, build a new automated incidator, and change Count to Sum.  

Add a script, and have it process exactly as it should in the formula, pulling scores in either from the pa_scores table or the table that the records came from originally.  When you 'return' a number from the formula, it becomes the score for that indicator, regardless of where it came from.  

The drawback is that you won't be able to drill into records this way, but if it's just a supporting score, that should be okay.  

 

Incidently, breakdowns still work on scores created this way, you just have to get a little more creative.  Instead of returning precisely one row, set it up the same way you would your Breakdown source - then each 'current' record will have the breakdown value, and you can use that in a regular breakdown to determine which bucket it should go in.  Remember scripts for Indicators want a value.  Scripts for Breakdowns want a sys_id that matches the Breakdown Source.  As long as you're returning appropriate values, PA will handle the rest.

View solution in original post

7 REPLIES 7

Hi, Josh!

Great news! I finally returned to this and implemented your suggestion. It worked! In case anyone else wants to do something similar, I'm going to describe exactly the steps I used...

Step 1: Click Indicator Sources within Sources under Performance Analytics in the left-navigation bar. Click New beside Indicator Sources. Set Name to Return.One.Record.DailyFrequency to DailyFacts Table to User [sys_user], and add a filter condition: User ID is admin. Click Submit.

Step 2: Click Scripts inside Automation under Performance Analytics. Click New beside Scripts. Set Name to Count.Business.Services.Higher.than.60%.FRR.DailyFacts table to User [sys_user]Script to:

var count_elements = function(threshold) {
    var count = 0;
    var denominator = new GlideRecord('pa_scores_l1');
    denominator.addQuery('breakdown',17); // 'Business Service' breakdown
    denominator.addQuery('indicator','11'); // '# Resolved Incidents' Indicator
    denominator.addQuery('start_at','>=',score_start.getGlideObject().getDate()); // The beginning of the date range
    denominator.addQuery('start_at','<=',score_end.getGlideObject().getDate()); // The end of the date range
    denominator.query();
    while (denominator.next()) {
        var numerator = new GlideRecord('pa_scores_l1');
        numerator.addQuery('breakdown',17); // 'Business Service' breakdown
        numerator.addQuery('indicator','313'); // '# Two-Reply Resolved Incidents' Indicator
        numerator.addQuery('start_at','>=',score_start.getGlideObject().getDate()); // The beginning of the date range
        numerator.addQuery('start_at','<=',score_end.getGlideObject().getDate()); // The end of the date range
        numerator.query();
        while (numerator.next()) {
            if(denominator['element'] == numerator['element']) { // we have the same elements, so we can now do the calculation
               var score = (numerator['value']/denominator['value'])*100; // Calculate % Few-Reply Resolution
               if (score > threshold) {
                   count = count + 1;
               }
               break;
            }
        }
    }
    return count;
};
  
// This script will count the number of Business Services that have a % FRR greater than the number passed to the function below.
count_elements(60);

Step 3: Click Automated Indicators inside Indicators under Performance Analytics. Click New beside Indicators [Automated View]. Set Name to # Business Services with > 60% Few Reply Resolution (Daily)Frequency to DailyDirection to MaximizeUnit to #, and Precision to 0. On the Source tab, set Indicator Source to Return.One.Record.DailyAggregate to SumScripted to EnabledScript to Count.Business.Services.Higher.than.60%.FRR.Daily, and Value when Nil to 0. Click Submit.

Thanks so much for your help!

-Gray

No problem!  Congrats on getting it going!  It's also awesome that you came back to post the method.  That makes it much better for everyone else who may run into something similar going forward.

gyedwab
Mega Guru

If you in the future want to do this codelessly, and still be able to drill down, you can look at doing this with Explore Analytics.

What I did for this was... first, I created the report with the Incident Awesomeness % by Business service - in this case, creating a real-time report on two different tables (calls, in my MySQL database, and Incident, in ServiceNow), and applying a formula:

find_real_file.png

find_real_file.png

 

Once I had the view, I used the menu option to Create a composite view. This allows me to treat this "incident awesomeness" field as if it was a field in ServiceNow... then I can just filter on Incident awesomeness > 100%

find_real_file.png find_real_file.png

 

Furthermore, I can also use 'binning' to compare the distribution of business services by % awesomeness:

find_real_file.png

 

find_real_file.png