logo

NJP

How to Identify Duplicate Records by Multiple Fields in ServiceNow

ServiceNow Developer Pro-Tips · Mar 28, 2024 · article

[ ](https://handbook.snc.guru)

> “_I have some records in a table which are duplicates. In this case, I can only identify “duplicate records” by whether several fields are identical; not just one. For example, let’s say I want to identify Incidents where the Short description, Assignment group, and Assigned to user are all the same. If only one or two of those fields match, but one of them is different, then the records are not duplicates. The’re only duplicates if all three fields are the same._
>
> _Is there any way to accomplish this with a script? Maybe by using_ `_GlideAggregate_`_?_”

Thanks for your question, and **indeed, there is** a way to identify duplicate records based on multiple matching fields in a script in ServiceNow!

At first glance, you might think that the [GlideAggregate](https://developer.servicenow.com/dev.do#!/reference/api/washingtondc/server/no-namespace/c%5FGlideAggregateScopedAPI:~:text=GlideAggregate) APIs do not support any direct mechanism by which to identify duplicate records across multiple identical fields. However, there **_is_** _a way_!
By getting just a smidge clever, we can call the `[.groupBy()](https://developer.servicenow.com/dev.do#!/reference/api/washingtondc/server/no-namespace/c%5FGlideAggregateScopedAPI#r%5FScopedGlideAggregateGroupBy%5FString)` API method multiple times, in combination with the `[.addAggregate()](https://developer.servicenow.com/dev.do#!/reference/api/washingtondc/server/no-namespace/c%5FGlideAggregateScopedAPI#r%5FScopedGlideAggregateAddAggregate%5FString%5FString)` and `[.addHaving()](https://developer.servicenow.com/dev.do#!/reference/api/washingtondc/server%5Flegacy/c%5FGlideAggregateAPI#r%5FGlideAggregate-addHaving%5FString%5FString%5FString?navFilter=addHaving)` methods, to accomplish our goal of identifying duplicate records with more than one field that are identical.

Consider the following code, for example - which is a basic example of how to find duplicates in a table based on multiple fields:

> **Note**: _This is **not the optimal solution**. There is far more optimal and functional code at the end of this article. If you just came here for the solution and want to skip the the learning, you can **[click here](#optimal%5Fsolution)**._

```javascript
var dupeCount = 0;
var gaMyTableDuplicate = new GlideAggregate('incident');
gaMyTableDuplicate.addAggregate('COUNT');
gaMyTableDuplicate.groupBy('short_description');
gaMyTableDuplicate.groupBy('assignment_group');
gaMyTableDuplicate.groupBy('assigned_to');
gaMyTableDuplicate.addHaving('COUNT', '>', 1);
gaMyTableDuplicate.query();

while (gaMyTableDuplicate.next()) {
dupeCount = gaMyTableDuplicate.getAggregate('COUNT');
gs.info(
dupeCount + ' records found with the following identical values:\n' +
'•Short description: ' + (gaMyTableDuplicate.getValue('short_description') || '(blank)') + '\n' +
'•Assignment group: ' + (gaMyTableDuplicate.assignment_group.getDisplayValue() || '(blank)') + '\n' +
'•Assigned to: ' + (gaMyTableDuplicate.assigned_to.getDisplayValue() || '(blank)') + '\n\n'
);
}
```

This basic method of using the GlideAggregate `.groupBy()` method allows us to group by fields, count groups matching on those fields, and filter where the groups have more than one record in them (aka, duplicates!)

When we execute this in a background script, we get results printed out which look something like this:

5 records found with the following identical values:
•Short description: (blank)
•Assignment group: Team Development Code Reviewers
•Assigned to: Tim Woodruff

Cool, that works!

Now let's drop it into a function we can call, and add some arguments, and some input validation.

```javascript
function getMultiFieldDupes(tableName, arrDupeFields) {
var iDupeField, gaMyTableDuplicate;
var dupeCount = 0;

if (typeof tableName !== 'string' || !tableName) {
throw new Error(
'getMultiFieldDupes(): tableName must be a string consisting of a valid ' +
'table name in the ServiceNow database.'
);
}

if ( //If arrDupeFields is not an array or a string, or if it's an array but it's empty
typeof arrDupeFields === 'undefined' ||
!arrDupeFields ||
(!Array.isArray(arrDupeFields) && typeof arrDupeFields !== 'string') ||
!arrDupeFields.length
) {
throw new Error(
'getMultiFieldDupes(): arrDupeFields must be a string with a single ' +
'field name, or an array of strings - each string representing a ' +
'field name in the ' + tableName + ' table.'
);
}

//If arrDupeFields is a string, convert it to an array.
if (typeof arrDupeFields === 'string') {
arrDupeFields = arrDupeFields.split(',');
}

gaMyTableDuplicate = new GlideAggregate(tableName);
gaMyTableDuplicate.addAggregate('COUNT');

//Group by each field in the arrDupeFields array
for (
iDupeField = 0;
iDupeField < arrDupeFields.length;
iDupeField++
) {
gaMyTableDuplicate.groupBy(arrDupeFields[iDupeField]);
}

gaMyTableDuplicate.addHaving('COUNT', '>', 1);
gaMyTableDuplicate.query();

while (gaMyTableDuplicate.next()) {
dupeCount = gaMyTableDuplicate.getAggregate('COUNT');
gs.info( //todo: replace with dynamic field values - but whatever, this is just an intermediary example.
dupeCount + ' records found with the following identical values:\n' +
'•Short description: ' + (gaMyTableDuplicate.getValue('short_description') || '(blank)') + '\n' +
'•Assignment group: ' + (gaMyTableDuplicate.assignment_group.getDisplayValue() || '(blank)') + '\n' +
'•Assigned to: ' + (gaMyTableDuplicate.assigned_to.getDisplayValue() || '(blank)') + '\n\n'
);
}
}
```

Now we can call this function with a table name and an array of fields to group by, and it will return pretty much the same results as before.

Next, let's add some additional features and functionality.

I noticed that with the [first version](#v1)of our code, we were outputting records where some of the fields (such as the short description) were blank.

This may be fine, but I can imagine a scenario in which we may not want that.
Therefore, let's add a feature to allow us to filter out records where any of a specified (optional) list of fields is blank.

Since we may want to get the sys\_ids for each duplicate record within a given duplicate "type" (each specific combination of unique field values), let's also add a feature to return an array of sys\_ids for each duplicate record found within each duplicate "type".

And finally, rather than printing it out, let's have the function return an array of objects with details about each set of duplicates found.

---

# Optimal Solution

This solution supports specifying one or more field(s) you want to compare for duplicates (yes, it works with only a single dupe-field as well), specifying an optional list of fields to filter out if they're blank, and even optionally getting a list of sys\_ids for all of the records which match each duplicate scenario!

```javascript
/**
* Get records with duplicate values in multiple fields, and return a list of the records'
* counts and the dupe fields' values.
*
* @param {string} tableName - The table to check for duplicates. Must be a string.
*
* @param {string|string[]} arrDupeFields - The fields to check for duplicates.
* Must be a string or an array of strings.
*
* @param {string|string[]} [nonBlankFields=[]] - This optional parameter, if specified, will
* be an array of strings consisting of the names of the fields which should not be allowed
* to be blank when checking for duplicates.
* To put it another way, if any of the fields specified in the `nonBlankFields` array are
* blank, then the record should not be considered a duplicate.
* Note that the fields specified in nonBlankFields do NOT need to also be specified in
* arrDupeFields.
*
* @param {boolean} [getDupeSysIds=false] - If true, the sys_ids of the records with the
* duplicate values will be included in the returned object. If false, they will not be
* included.
* This may have a performance impact, as it requires an additional query for each
* duplicate combination, so use with caution.
* Default is false.
*
* @returns {{dupeCount: (*|number), fields: {}}[]} - An array of objects, each object
* representing a confluence of duplicate values in the specified fields - a specific
* combination of field values - and the number of records that have that combination of
* those values in the specified fields.
*/
function getMultiFieldDupes(tableName, arrDupeFields, nonBlankFields, getDupeSysIds) {
var gaMyTableDuplicate, grDupe, iNonBlankField, iDupeField, objDupeRecord;
var arrDupeRecords = [];
var dupeCount = 0;

/***** INPUT VALIDATION *****/

getDupeSysIds = (typeof getDupeSysIds === 'boolean') ? getDupeSysIds : false;

if (typeof tableName !== 'string' || !tableName) {
throw new Error(
'getMultiFieldDupes(): tableName must be a string consisting of a valid ' +
'table name in the ServiceNow database.'
);
}

if ( //If arrDupeFields is not an array or a string, or if it's an array but it's empty
typeof arrDupeFields === 'undefined' ||
!arrDupeFields ||
(!Array.isArray(arrDupeFields) && typeof arrDupeFields !== 'string') ||
!arrDupeFields.length
) {
throw new Error(
'getMultiFieldDupes(): arrDupeFields must be a string with a single ' +
'field name, or an array of strings - each string representing a ' +
'field name in the ' + tableName + ' table.'
);
}

//If arrDupeFields is a string, convert it to an array.
if (typeof arrDupeFields === 'string') {
arrDupeFields = arrDupeFields.split(',');
}

//If nonBlankFields is undefined, null, or an empty string, set it to an empty array.
//If it's a string, convert it to an array.
if (typeof nonBlankFields === 'undefined' || !nonBlankFields) {
nonBlankFields = [];
} else if (typeof nonBlankFields === 'string') {
//Splitting just in case the input data is a comma-separated string - which it
// shouldn't be, but I don't trust anyone who calls this code. They seem sus.
nonBlankFields = nonBlankFields.split(',');
} else if (!Array.isArray(nonBlankFields)) {
//If it's not a string or an array or undefined, throw an error because wth am I s'posed to do with that
throw new Error(
'getMultiFieldDupes(): nonBlankFields must be a string with a single ' +
'field name, or an array of strings - each string representing a ' +
'field name in the ' + tableName + ' table.'
);
}

/***** ACTUALLY DOING THE THING *****/
gaMyTableDuplicate = new GlideAggregate(tableName);
gaMyTableDuplicate.addAggregate('COUNT');

//Group by each field in the arrDupeFields array
for (
iDupeField = 0;
iDupeField < arrDupeFields.length;
iDupeField++
) {
gaMyTableDuplicate.groupBy(arrDupeFields[iDupeField]);
}

//If any nonBlankFields were specified, add a query to exclude records where
// any of those fields are blank.
for (
iNonBlankField = 0;
iNonBlankField < nonBlankFields.length;
iNonBlankField++
) {
gaMyTableDuplicate.addNotNullQuery(nonBlankFields[iNonBlankField]);
}

//Only show records with more than one match (duplicates)
gaMyTableDuplicate.addHaving('COUNT', '>', 1);
gaMyTableDuplicate.query();

while (gaMyTableDuplicate.next()) {
dupeCount = gaMyTableDuplicate.getAggregate('COUNT');

//Populate the arrDupeRecords array with some info about the records that have duplicates
objDupeRecord = {
"dupeCount": dupeCount,
"fields": {}
};

//For each field in the arrDupeFields array, add that field's value to
// the objDupeRecord.fields object.
for (
iDupeField = 0;
iDupeField < arrDupeFields.length;
iDupeField++
) {
objDupeRecord.fields[arrDupeFields[iDupeField]] = gaMyTableDuplicate.getValue(arrDupeFields[iDupeField]);
}

if (getDupeSysIds) {
objDupeRecord.dupe_sys_ids = [];
//Add the sys_ids of all the records that have this combination of dupe fields in objDupeRecord.dupe_sys_ids:
grDupe = new GlideRecord(tableName);

for (
iDupeField = 0;
iDupeField < arrDupeFields.length;
iDupeField++
) {
grDupe.addQuery(arrDupeFields[iDupeField], objDupeRecord.fields[arrDupeFields[iDupeField]]);
}

grDupe.query();
while (grDupe.next()) {
objDupeRecord.dupe_sys_ids.push(grDupe.getUniqueValue());
}
}

arrDupeRecords.push(objDupeRecord);
}

return arrDupeRecords;
}
```

# Usage

## Example 1: Duplicate Incidents with sys\_ids

Calling the function in this way will get a list of field values **and sys\_ids** for records which are duplicates based on the Short description, Assignment group, and Assigned to fields all matching. It will not count any records with a blank Short description or Assigned to field as duplicates.

```javascript
var dupeRecords;
dupeRecords = getMultiFieldDupes(
'incident', //Table name
['short_description', 'assignment_group', 'assigned_to'], //Fields to check for duplicates
['short_description','assigned_to'], //Fields that must not be blank
true //Get the sys_ids of the records with duplicates
);
//Print out the results:
gs.info(
'Found ' + dupeRecords.length + ' duplicate types:\n' +
JSON.stringify(dupeRecords, null, 2)
);
```

### Output:

```json
[
{
"dupeCount": "2",
"fields": {
"short_description": "Watchlist ticket",
"assignment_group": "cfcbad03d711110050f5edcb9e61038f",
"assigned_to": "713e4bd0dba90110495d70f33996198b"
},
"dupe_sys_ids": [
"3c4cf41e1bd069900f679713b24bcbff",
"b44cb01e1bd069900f679713b24bcb36"
]
},
{
"dupeCount": "4",
"fields": {
"short_description": "Some Short Description",
"assignment_group": "cfcbad03d711110050f5edcb9e61038f",
"assigned_to": "713e4bd0dba90110495d70f33996198b"
},
"dupe_sys_ids": [
"0a8fe93a1b50e9900f679713b24bcbb6",
"0a9ab1041ba4ed900f679713b24bcb0d",
"134542be1b90e9900f679713b24bcba6",
"1511c27a1b90e9900f679713b24bcbb7"
]
}
]
```

## Example 2: Users with duplicate first+last names

This function-call will get a list of users who have the same first and last name. It will not get the sys\_ids of each duplicate user, but will give you the list of first+last names corresponding to duplicates.

```javascript
var dupeRecords = getMultiFieldDupes(
'sys_user', //Table name
['first_name', 'last_name'],
null, //No fields must be non-blank
false //Don't get the sys_ids of the records with duplicates
);
gs.info(
'Found ' + dupeRecords.length + ' duplicate types:\n' +
JSON.stringify(dupeRecords, null, 2)
);
```

### Output:

```json
[
{
"dupeCount": "15",
"fields": {
"first_name": "",
"last_name": ""
}
},
{
"dupeCount": "2",
"fields": {
"first_name": "John",
"last_name": "Smith"
}
}
]
```

## Example 3: Incidents with duplicate Short descriptions

Calling the function in this way will return the Incident Short descriptions which are duplicates. This is to demonstrate that this function works whether you specify one dupe field, or multiple.

This will also filter out any records with a blank Assignment group field, just to demonstrate that the blank field filter does not need to operate exclusively on a field which is included in your list of dupe-fields.

```javascript
var dupeRecords = getMultiFieldDupes(
'incident', //Table name
['short_description'], //Field to check for duplicates
'assignment_group', //Field that must not be blank
false //Don't get the sys_ids of the records with duplicates
);
gs.info(
'Found ' + dupeRecords.length + ' duplicate types:\n' +
JSON.stringify(dupeRecords, null, 2)
);
```

### Output:

```json
[
{
"dupeCount": "5",
"fields": {
"short_description": ""
}
},
{
"dupeCount": "2",
"fields": {
"short_description": "Reset my password"
}
}
]
```

Thanks for reading! If you enjoyed this article or found this tool helpful, please consider sharing it on your favorite social media so others can find it too! If you want to see more from SN Pro Tips and [Tim Woodruff](https://li.snc.guru), consider subscribing below or following Tim on [LinkedIn](https://li.snc.guru)!

---

## Subscribe

Sign up with your email address to receive news and updates.

First Name Last Name

Email Address Sign Up

We respect your privacy.

Thank you!

* [ 2026](https://snprotips.com/blog?year=2026)
* Jan 8, 2026 [Flow Designer vs. Scripting - REST Message Performance](https://snprotips.com/blog/) Jan 8, 2026
* [ 2025](https://snprotips.com/blog?year=2025)
* Sep 29, 2025 [Find Filthy Inefficient Single-Record Queries FAST](https://snprotips.com/blog/) Sep 29, 2025
* Sep 14, 2025 [Communicating Changes to Your Users (& Setting Default User Preferences in ServiceNow)](https://snprotips.com/blog/) Sep 14, 2025
* Mar 24, 2025 [Calculate Distance Between Two Locations in ServiceNow (without an API call!)](https://snprotips.com/blog/) Mar 24, 2025
* Mar 11, 2025 [5 Ways to Check your ServiceNow Instance for DANGEROUS CODE in Less Than 5 minutes](https://snprotips.com/blog/) Mar 11, 2025
* [ 2024](https://snprotips.com/blog?year=2024)
* Mar 28, 2024 [How to Identify Duplicate Records by Multiple Fields in ServiceNow](https://snprotips.com/blog/) Mar 28, 2024
* Mar 7, 2024 [How to Merge Personal & Company ServiceNow Accounts](https://snprotips.com/blog/) Mar 7, 2024
* Feb 12, 2024 [5 Lessons About Programming From Richard Feynman](https://snprotips.com/blog/) Feb 12, 2024
* [ 2023](https://snprotips.com/blog?year=2023)
* Jul 5, 2023 [Managing Instance-Specific System Properties for Dev/Test/Prod in ServiceNow](https://snprotips.com/blog/) Jul 5, 2023
* Apr 28, 2023 [Your ACLs and Business Rules are Broken (Here's How to Fix Them)](https://snprotips.com/blog/) Apr 28, 2023
* [ 2022](https://snprotips.com/blog?year=2022)
* Dec 13, 2022 [ServiceNow Developers: BE THE GUIDE!](https://snprotips.com/blog/) Dec 13, 2022
* Oct 19, 2022 [A Faster, More Efficient Client-side GlideRecord (Free tool!)](https://snprotips.com/blog/) Oct 19, 2022
* Oct 9, 2022 [Animated Loading Message & Collapsible Details on ServiceNow Form or Field (Client-side)](https://snprotips.com/blog/) Oct 9, 2022
* Aug 23, 2022 [Using .addJoinQuery() & How to Query Records with Attachments in ServiceNow](https://snprotips.com/blog/) Aug 23, 2022
* Aug 18, 2022 [Free, Simple URL Shortener for ServiceNow Nerds (snc.guru)](https://snprotips.com/blog/) Aug 18, 2022
* Aug 16, 2022 [How to Get and Parse ServiceNow Journal Entries as Strings/HTML](https://snprotips.com/blog/) Aug 16, 2022
* Aug 14, 2022 [New tool: Get Latest Version of ServiceNow Docs Page](https://snprotips.com/blog/) Aug 14, 2022
* Mar 4, 2022 [How to Set or Change ServiceNow Application's Repository URL, Credentials, or SSH Key](https://snprotips.com/blog/) Mar 4, 2022
* Feb 7, 2022 [How to return a CSV file from a Scripted REST API (SRAPI) in ServiceNow](https://snprotips.com/blog/) Feb 7, 2022
* [ 2021](https://snprotips.com/blog?year=2021)
* May 3, 2021 [Adding a Guided Setup to Your ServiceNow Application](https://snprotips.com/blog/) May 3, 2021
* Apr 27, 2021 [Use Automated Tests to Validate "Guided Setup" Completion & Functionality.](https://snprotips.com/blog/) Apr 27, 2021
* Feb 11, 2021 ["Processors", SRAPIs, and How to Run a Script and Redirect a User From a URL in ServiceNow](https://snprotips.com/blog/) Feb 11, 2021
* [ 2020](https://snprotips.com/blog?year=2020)
* Nov 17, 2020 [SN Guys is now part of Jahnel Group!](https://snprotips.com/blog/) Nov 17, 2020
* Sep 14, 2020 [Better ServiceNow Notifications (& Another FREE Tool!)](https://snprotips.com/blog/) Sep 14, 2020
* Jul 31, 2020 [Debugging Client & Catalog Client Scripts in ServiceNow](https://snprotips.com/blog/) Jul 31, 2020
* Jan 20, 2020 [Getting Help from the ServiceNow Community](https://snprotips.com/blog/) Jan 20, 2020
* [ 2019](https://snprotips.com/blog?year=2019)
* Dec 18, 2019 [Can ServiceNow Script Includes Use the "current" Variable?](https://snprotips.com/blog/) Dec 18, 2019
* Nov 18, 2019 [Handling 'text/plain' and Other Unsupported Content Types in ServiceNow Scripted REST APIs](https://snprotips.com/blog/) Nov 18, 2019
* Apr 21, 2019 [Understanding Attachments in ServiceNow](https://snprotips.com/blog/) Apr 21, 2019
* Apr 10, 2019 [Using Custom Search Engines in Chrome to Quickly Navigate ServiceNow](https://snprotips.com/blog/) Apr 10, 2019
* Apr 4, 2019 [Set Catalog Variables from URL Params (Free tool)](https://snprotips.com/blog/) Apr 4, 2019
* Apr 1, 2019 [Outlook for Android Breaks Email Approvals (+Solution)](https://snprotips.com/blog/) Apr 1, 2019
* Mar 11, 2019 [GlideFilter is Broken - Free Tool: “BetterGlideFilter”](https://snprotips.com/blog/) Mar 11, 2019
* Feb 27, 2019 [Making Update Sets Smarter - Free Tool](https://snprotips.com/blog/) Feb 27, 2019
* [ 2018](https://snprotips.com/blog?year=2018)
* Nov 29, 2018 [How to Learn ServiceNow](https://snprotips.com/blog/) Nov 29, 2018
* Nov 6, 2018 [ServiceNow & ITSM as a Career?](https://snprotips.com/blog/) Nov 6, 2018
* Oct 19, 2018 [Asynchronous onSubmit Catalog/Client Scripts in ServiceNow](https://snprotips.com/blog/) Oct 19, 2018
* Oct 11, 2018 [How to do Massive, Slow Database Operations Efficiently With Event-Driven Recursion](https://snprotips.com/blog/) Oct 11, 2018
* Sep 18, 2018 [Broken Queries & Query Business Rules in ServiceNow](https://snprotips.com/blog/) Sep 18, 2018
* Sep 7, 2018 [JournalRedactor - Easily Redact or Delete Journal Entries in ServiceNow!](https://snprotips.com/blog/) Sep 7, 2018
* Jul 23, 2018 [Admin Duty Separation with a Single Account](https://snprotips.com/blog/) Jul 23, 2018
* Jun 19, 2018 [Improving Performance on Older Instances with Table Rotation](https://snprotips.com/blog/) Jun 19, 2018
* Jun 4, 2018 [New Free Tool: Login Link Generator](https://snprotips.com/blog/) Jun 4, 2018
* May 29, 2018 [Learning ServiceNow: Second Edition!](https://snprotips.com/blog/) May 29, 2018
* Apr 17, 2018 [Upgrading From Express to Enterprise: What's Missing](https://snprotips.com/blog/) Apr 17, 2018
* Apr 12, 2018 [If a Genie Gave Me Three Wishes, I'd Use Them All to "Fix" Scope](https://snprotips.com/blog/) Apr 12, 2018
* Mar 19, 2018 [Service Catalog "Try in Portal" button](https://snprotips.com/blog/) Mar 19, 2018
* Mar 15, 2018 [Video: Custom Output Transition Conditions From a Single Workflow (Script) Activity](https://snprotips.com/blog/) Mar 15, 2018
* Feb 11, 2018 [We have a new book! ](https://snprotips.com/blog/) Feb 11, 2018
* [ 2017](https://snprotips.com/blog?year=2017)
* Nov 6, 2017 [Requiring Attachments (& Other Miracles) in Service Portal](https://snprotips.com/blog/) Nov 6, 2017
* Sep 12, 2017 [Handling TimeZones in ServiceNow (TimeZoneUtil)](https://snprotips.com/blog/) Sep 12, 2017
* Jul 27, 2017 [How to Enable DOM Manipulation in ServiceNow Service Portal Catalog Client Scripts](https://snprotips.com/blog/) Jul 27, 2017
* Jun 25, 2017 [What's New in ServiceNow: Jakarta (Pt. 1)](https://snprotips.com/blog/) Jun 25, 2017
* Jun 4, 2017 [Powerful Scripted Text Search in ServiceNow](https://snprotips.com/blog/) Jun 4, 2017
* May 9, 2017 [Work at Lightspeed: ServiceNow's Plan for World Domination](https://snprotips.com/blog/) May 9, 2017
* Apr 9, 2017 [Avoiding Pass-By-Reference Using getValue() & setValue()](https://snprotips.com/blog/) Apr 9, 2017
* Apr 4, 2017 ["Learning ServiceNow" is Now Available for Purchase!](https://snprotips.com/blog/) Apr 4, 2017
* Mar 12, 2017 [reCAPTCHA in ServiceNow CMS/Service Portal](https://snprotips.com/blog/) Mar 12, 2017
* [ 2016](https://snprotips.com/blog?year=2016)
* Dec 20, 2016 [Pro Tip: Use updateMultiple() for Maximum Efficiency! ](https://snprotips.com/blog/) Dec 20, 2016
* Dec 2, 2016 [We're Writing a Book! ](https://snprotips.com/blog/) Dec 2, 2016
* Nov 10, 2016 [Chrome Extension: Load in ServiceNow Frame](https://snprotips.com/blog/) Nov 10, 2016
* Sep 7, 2016 [Force-Include Any Record Into an Update Set](https://snprotips.com/blog/) Sep 7, 2016
* Sep 1, 2016 [GlideRecord Pagination - Page through your GlideRecord query](https://snprotips.com/blog/) Sep 1, 2016
* Jul 17, 2016 [Granting Temporary Roles/Groups in ServiceNow](https://snprotips.com/blog/) Jul 17, 2016
* Jul 15, 2016 [Scripted REST APIs & Retrieving RITM Variables via SRAPI](https://snprotips.com/blog/) Jul 15, 2016
* May 17, 2016 [What's New in Helsinki?](https://snprotips.com/blog/) May 17, 2016
* Apr 27, 2016 [Customizing UI16 Through CSS and System Properties](https://snprotips.com/blog/) Apr 27, 2016
* Apr 5, 2016 [ServiceNow Versions: Express Vs. Enterprise](https://snprotips.com/blog/) Apr 5, 2016
* Mar 28, 2016 [Update Set Collision Avoidance Tool: V2](https://snprotips.com/blog/) Mar 28, 2016
* Mar 18, 2016 [ServiceNow: What's New in Geneva & UI16 (Pt. 2)](https://snprotips.com/blog/) Mar 18, 2016
* Feb 22, 2016 [Reference Field Auto-Complete Attributes](https://snprotips.com/blog/) Feb 22, 2016
* Feb 6, 2016 [GlideRecord & GlideAjax: Client-Side Vs. Server-Side](https://snprotips.com/blog/) Feb 6, 2016
* Feb 1, 2016 [Make Your Log Entries Easier to Find](https://snprotips.com/blog/) Feb 1, 2016
* Jan 29, 2016 [A Better, One-Click Approval](https://snprotips.com/blog/) Jan 29, 2016
* Jan 25, 2016 [Quickly Move Changes Between Update Sets](https://snprotips.com/blog/) Jan 25, 2016
* Jan 20, 2016 [Customize the Reference Icon Pop-up](https://snprotips.com/blog/) Jan 20, 2016
* Jan 7, 2016 [ServiceNow: Geneva & UI16 - What's new](https://snprotips.com/blog/) Jan 7, 2016
* Jan 4, 2016 [Detect/Prevent Update Set Conflicts Before They Happen](https://snprotips.com/blog/) Jan 4, 2016
* [ 2015](https://snprotips.com/blog?year=2015)
* Dec 28, 2015 [SN101: Boolean logic and ServiceNow's Condition Builder](https://snprotips.com/blog/) Dec 28, 2015
* Dec 17, 2015 [Locate any record in any table, by sys\_id in ServiceNow](https://snprotips.com/blog/) Dec 17, 2015
* Dec 16, 2015 [Detecting Duplicate Records with GlideAggregate](https://snprotips.com/blog/) Dec 16, 2015
* Dec 11, 2015 [Array.indexOf() not working in ServiceNow - Solution! ](https://snprotips.com/blog/) Dec 11, 2015
* Dec 2, 2015 [Understanding Dynamic Filters & Checking a Record Against a Filter Using GlideFilter](https://snprotips.com/blog/) Dec 2, 2015
* Oct 20, 2015 [Bookmarklet: Load the current page in the ServiceNow frame](https://snprotips.com/blog/) Oct 20, 2015
* Aug 27, 2015 [Easily Clone One User's Access to Another User](https://snprotips.com/blog/) Aug 27, 2015

View original source

https://snprotips.com/blog/2024/how-to-identify-a-duplicate-record-by-multiple-fields-in-servicenow