How to use the “Not Exists” operator

General Add comments
by:

Once I was at a customer who wanted to know which CIs in the Configuration Management Database (CMDB) were not linked to an IT service. I discovered that ServiceNow didn’t posses the capability to do this easily by using some kind of operator like “Not Exists”, an SQL statement to filter-out the correct related Configuration Items.

Exists vs Not Exists

What is a Not Exists operator? Basically, it’s a conditional operator to test for the existence or non-existence of a set of values returned by a sub-query.


Example: Correlated Sub-query with NOT EXISTS
Suppose you are working with the following tables:

  • CMDB contains the set of all Configuration Items
  • IT Service contains the set of all Services
  • Relations contains the set of all relations

As shown in the diagram below, the intersection of these three tables contains the data for all Configuration Items that has a relationship with an IT Service


Suppose you want to list all CIs that are not related to an IT Service as shown in the diagram below.’


The following SQL query accomplishes this task by using a correlated sub-query and the NOT EXISTS operator:

select *
from CMDB
where not exists(
    select Relations .CI
    from CMDB Relations ITservices
    where Relations.CI = CMDB.id and Relations.ITservice = ITservices.id
)

Unfortunately this SQL query cannot be used in ServiceNow directly. It is not going to work this way. But there is an option to do this using:

  • A Database View
  • A Script
  • A Report or list using filters to call the script

SNC – Database View:
Create a database view called “u_config_newtest_no_join” with the following View Tables:


Not Exists Script:
[cc lang=”javascript”]
var DBviewUtils = Class.create();
DBviewUtils.prototype = {
initialize: function() {
},
// List of CI
DBV_NOTexists : function() {
var list = “”;
var qb = new GlideRecord(‘cmdb_ci’);
qb.query();
while(qb.next()){
qa = new GlideAggregate(‘u_config_newtest_no_join’);
qa.addAggregate(‘count’); //Count aggregate (only necessary for a count of items of each child)
qa.orderByAggregate(‘count’); //Count aggregate ordering
qa.groupBy(‘rel_child’); //Group aggregate by child
qa.addQuery(‘rel_child’,qb.sys_id);
qa.query();
if(qa.next()){
//do nothing
}else{
list += qb.sys_id + ‘,’;
}
}
return list;
},
type: ‘DBviewUtils’
};
[/cc]
SNC – Report:
Create a report as described below and save it. The list contains all CIs which are not related to a IT Service.

Let me know if you have any questions. You can reach me at .img[at].img.

Leave a Reply