Let's POWER Automate

From no-code to low-code

Menu
  • Expressions
  • Filters
  • General
  • Application specific solutions
    • Dataverse
    • Excel
    • Forms
    • Outlook
    • Planner
    • Power Apps
    • SharePoint
    • Teams
  • Triggers
  • Ready to use solutions
    • Approval Process Template
    • Task Delegation App
    • The Ultimate Power Automate expressions cheat sheet
    • Power Automate HTTP requests to SharePoint cheat sheet
    • Power Automate HTTP requests to Graph API cheat sheet
  • ABOUT ME
  • Get help with your flow
  • POWER PLATFORM SERVICES
Menu

How to compare items in two SharePoint lists in Power Automate

Posted on June 6, 2021June 6, 2021 by Tom

“My scheduled Power Automate flow synchronises multiple SharePoint lists into one, is there a way to compare the items and send a report with the changes?”


When you synchronise two or more SharePoint lists on regular basis, there’re (at least) two concerns. One of them is the performance. You probably don’t want the flow to update everything with each run even if there’re no changes, and at the same time you don’t want to compare all the items with each other. In both situations you’d end up with a flow that’d run for ages and/or consume a lot of API calls.

The second concern is to keep an overview of what’s happening in the lists. Which items were updated? Which columns were updated in the items? It might be very helpful to create a report with all the changes during the synchronisation. And that’s what this post will be about, how to find and report the changes between the lists.

This post will be about one-way synchronisation from source list(s) to target list, without deletion of items. There must be also a unique identifier to connect the items in those lists, and the columns to synchronise must have the same internal name.

Define the synchronised columns

The flow begins with definition of the columns that are synchronised. Initialize variable of type array and store the column’s internal names inside. If it’s an object column, e.g. user or choice column, define the specific value to access. Use the array format as shown below to define the array.

[
  "Column1",
  "Column2"
]

Initialize also a variable of type string to store the information about the actual changes.

Get items from both lists

To compare the items, you must get the items. Add two ‘Get items’ actions, one leading to the source list, the other to the target list. Take all the items, without any filter or limitation.

The ‘value’ outputs of each of the ‘Get items’ will give you all the items in the lists. It’s the items you want to compare, find the differences, and update the ones in the target list.

Compare the items

What you want to avoid is ‘Apply to each’ inside ‘Apply to each’. Comparing all items in the first list with all items in the second list will take a very long time. Even for as little as 100 items in each list it’d lead to 10000 (100*100) loops.

Power Automate compare items SharePoint lists

Instead of the second ‘Apply to each’, use the ‘Filter array’ action. Instead of looping through all the items, filter only the ones with the same unique identifier, e.g. Title. Loop through the items from the source list, and for each of them find the corresponding item in the target list.

After the ‘Filter array’ you won’t work with the output from ‘Get items 2’ (the items in the target list) anymore. You’ll work only with the output from ‘Filter array’, the filtered item. That means you’ll have to use the expression item()?[‘column internal name‘] to access the item values, or add ‘Parse JSON’.

Compare the values in synchronised columns

Here you’ll finally use the columns defined in the first step. You should compare if the items are the same, if they have the same values in the columns or if they need an update. Since you don’t want to compare the columns one by one, you can turn all the values in the columns into a single string, and then compare that string. It’s a similar approach as in the trigger condition on column update with the concat(…) expression. Build two concat(…) expressions, one for item in the source list and one for the target list with the desired columns.

Source list:
concat(items('Apply_to_each_-_source_list_item')?['Title'],items('Apply_to_each_-_source_list_item')?['FLowPerson/Email'],items('Apply_to_each_-_source_list_item')?['TestChoiceColumn/Value'],items('Apply_to_each_-_source_list_item')?['Lookup/Id'])

Target list:
concat(item()?['Title'],item()?['FLowPerson/Email'],item()?['TestChoiceColumn/Value'],item()?['Lookup/Id'])

You must keep the order of the columns the same in both the expressions! Add ‘Apply to each’ to process the ‘Body’ output from the ‘Filter array’, and a condition to compare the expressions. Don’t worry about the ‘Apply to each’ here as the ‘Body’ should have only 1 item, that’s only 1 loop.

If the concat(…) expressions are equal, the items are the same. You don’t need to update them. If they’re not equal, you can update the item in the target list with values from the source list.

Get the changes

To get the actual changes if the concat(…) expressions are not equal, compare the columns one by one. Add another ‘Apply to each’ to loop through the array variable, through all the columns. In this loop you’ll compare each of the columns in the source and target items, the syntax is the same as when processing http requests. You’ll use the currently processed item ? [column/value internal name].

Currently processed item from target list comes from the 'Apply to each - single loop': 
items('Apply_to_each_-_target_list_item') 

Currently processed item from source list comes from the first 'Apply to each': 
items('Apply_to_each_-_source_list_item')

Add the currently processed column, you'll get the expressions for the condition:
items('Apply_to_each_-_target_list_item')?[items('Apply_to_each_-_compare_the_columns')]
...is equal to...
items('Apply_to_each_-_source_list_item')?[items('Apply_to_each_-_compare_the_columns')]

Note: the ‘Apply to each’ name in items(‘Apply_to_each….’)?… must correspond to the name of your ‘Apply to each’ actions!

And if the values are not equal, append information about the difference into the string variable. Again, you must address the right item from the right ‘Apply to each’, including the specific value. Don’t forget to add end of line to the string.

ID <ID of item from target list> column <column name> : <target list value> was updated to <source list value>

ID @{items('Apply_to_each_-_target_list_item')?['ID']} column @{items('Apply_to_each_-_compare_the_columns')}: @{items('Apply_to_each_-_target_list_item')?[items('Apply_to_each_-_compare_the_columns')]} was updated to @{items('Apply_to_each_-_source_list_item')?[items('Apply_to_each_-_compare_the_columns')]}

After everything is processed, you’ll have information about all the changes in the variable.

Power Automate compare items SharePoint lists and display changes

Below is the full diagram of the flow.

Power Automate compare items SharePoint lists

Summary

Following this Power Automate solution to compare items in various SharePoint lists, I think the most complicated part is to not get lost in it. There’re multiple ‘Apply to each’ actions, each of them contains a different value. One ‘Apply to each’ to process the items in the source list one by one. The second ‘Apply to each’ to take the corresponding item in the target list (which is not really looping as it’ll contain just a single item). And the third ‘Apply to each’ to check all the predefined column one by one if needed.

Then it’s up to using the SharePoint column internal name, navigating in the JSON representation of the SharePoint items, and saving some work in the condition with the concat(…) expression.


🚀 Master Power Automate

Join 2,000+ professionals getting actionable Power Automate tutorials, solutions, cheat sheets & tips every week.

No spam. Unsubscribe anytime.

27 thoughts on “How to compare items in two SharePoint lists in Power Automate”

  1. Tim says:
    September 4, 2021 at 7:44 pm

    Dear Tom,

    Thank you for your website!
    Your solutions are the most elegant and helpful!
    I have a little question regarding the above flow, though….

    I am wondering if the same logic can be applied to compare SP List and Excel table?
    Will it work if “when file modified”, I will get items from SP List, then get rows from Excel file, concat the results in two strings, and compare?

    Reply
    1. Tom says:
      September 5, 2021 at 5:13 pm

      Hello Tim,
      I believe you can apply the same logic to compare SharePoint list with Excel file, but you should be careful about the more complex data types in SharePoint – choice, lookup, people picker, and date columns. Those might need some formatting on one or the other side, e.g. using the [‘Column/Value’] to get only the value from SharePoint or formatDateTime() to convert the date into the same format.

      Reply
  2. Adrian says:
    September 21, 2021 at 6:25 am

    this is wonderful! I’m trying to compare a sharepoint list with what is in “search for users”, the column names are different in the concat, what I’m trying to figure out is how I can make use of the var_column array if source and target have different names? maybe I missed something fundamental on where var_column is assigned values?

    Reply
    1. Tom says:
      September 26, 2021 at 7:17 pm

      Hello Adrian,
      you can’t use that solution if source and target have different names. You can use it to compare the values with the concat(…), but you can’t compare the columns one by one as all of them are defined in the same array. You’d need two arrays, one array for each list of the columns and then loop through both of them at the same time, but that’s much more complex solution that the one described and too complex to describe it in a comment. The best approach would be to make the column names the same, if that’s possible.

      Reply
  3. Adrian says:
    September 27, 2021 at 7:03 am

    Thanks Tom! this solution is great for a few other things I’m cooking, and I’ve already learned so much from your posts – glad I stumbled upon you!

    Reply
  4. Mariam says:
    January 6, 2022 at 4:16 pm

    Hi , I followed through but my case is a bit different , got stuck in the condition path.so I am trying to copy one item from a Source list to a Target list, they both have different records but have a matching email. I am trying to copy a particular number(Request Number) using the emails to match both both list i.e. I would like to copy the request number from source list to target list for abc@gmail.com . please help. Thanks

    Reply
    1. Tom says:
      January 10, 2022 at 8:58 pm

      Hello Mariam,
      you should lookup the item from the 2nd list as described here: https://tomriha.com/how-to-lookup-data-in-another-sharepoint-list-in-power-automate/, and then update the item in the 2nd list using the ID returned by ‘Get items’ and the values from the 1st list.

      Reply
  5. Alina says:
    January 18, 2022 at 7:51 pm

    Hi Tom,
    Thank you for providing this solution. I’m doing everything you indicate, however I’m getting no results on the Filter Array comparison. I even added a “trim” in front of each in case I was picking blank spaces somewhere. Still I get no results. Both items are “single line of text” in the respective SharePoint lists. Any suggestions on what to check for?

    Thank you!

    Reply
    1. Tom says:
      January 19, 2022 at 11:22 am

      Hello Alina,
      I’d try 3 things:

      1. Check if you’re using the right dynamic contents in the ‘Filter array’ action
      2. Add a ‘Compose’ action before the ‘Filter array’ and store the value (Title on the screenshots) from ‘Get items’ in that action. That way you’ll see in the flow run history what value it used for the filter.
      3. Check also input of the ‘Filter array’ in the flow run history searching for the value (Title on the screenshot) from ‘Get item’, if there’s an item with the value and if you’re using the right dynamic content to reference it
      Reply
  6. Cindy says:
    February 18, 2022 at 1:56 pm

    Hi Tom,

    I understand you cannot start a flow with an action and initialize variable is an action.

    I would like to know how what trigger was used in this flow.

    I’ve tried using manually trigger but it doesn’t serve my purpose

    Reply
    1. Tom says:
      February 19, 2022 at 11:42 am

      Hello Cindy,
      I used the Recurrence trigger in the flow to compare the lists on regular basis, but it’s up to you how/when you want to trigger it.

      Reply
  7. Daniel Gil says:
    March 4, 2022 at 9:48 pm

    Hi Tom,
    I have a similar case but I have not been able to solve it, I would really appreciate your help,

    I have two lists, List1 with a Date Column named ‘StartDate’ and a Text Column named “Status” and the other List2 with holidays dates… I want to know if each date of my List2 (holidays) is greater than the StartDate and less than today’s date for items with Status = Active in my list time and each time the condition is true add 1 unit so at the end of the condition I have counted hoy many times condition went true for and update that value to a column in my List1… For example StartDate = 1 march, Today= 4 march, Holday Date = 2 march, Holiday Date= 3 Holday Date = 1april… For today Condition is true two times so update a “2” in my colum… and if I see my list april 2 it will have a “3”. I will Recurrence trigger to update the column daily.
    I hope I was clear and Thanks a Lot!

    Reply
    1. Tom says:
      March 9, 2022 at 7:59 pm

      Hello Daniel,
      that sounds a bit too complicated for a comment, I’d recommend taking it to the Power Automate community forum and starting a topic there: https://powerusers.microsoft.com/t5/Microsoft-Power-Automate/ct-p/MPACommunity

      Reply
  8. Malgorzata says:
    June 17, 2022 at 10:25 am

    Hi Tom, this looks like a great solution for comparing price lists on regular basis – just what I was looking for to avoid using Excel as data source. I found myself a little bit stuck though. The flow runs correctly – but only returns values for 1 change and not from all columns. So for example, I got 3 columns to compare – title, field 1 and field7. Although multiple changes were made in field7, this would not be identified in the flow correctly and it ends just as if no changes were done. If I make a change to ‘Title’ column, the change is being identified correctly and gets returned in the end – but only for 1 item. If more items were changed, they won’t be listed.
    Would you perhaps have any hints what could be wrong here?

    Reply
    1. Tom says:
      June 22, 2022 at 9:04 pm

      Hello Malgorzata,
      I’d use the standard debugging approach – add ‘Compose’ action here and there and store the values the flow is processing, e.g. one ‘Compose’ to check the column names it’s processing, another ‘Compose’ to show the value in the currently processed column etc. In an ideal situation you should be able to go through the flow run history and see in all these debug ‘Compose’ actions what is happening and where and that might give you a hint what’s wrong.

      Reply
  9. Matthew says:
    June 28, 2022 at 8:06 pm

    Hello Tom,
    I have implemented what you made, but I just send a email when a element is diferent. So in the first ‘No’, I put a send email action. My problem is that my last commande (apply to each-target list item) never stop when the flow is tested. Do you know why?

    Reply
    1. Tom says:
      July 6, 2022 at 6:47 pm

      Hello Matthew,
      I’d check the dynamic contents used in the ‘Filter array’ action if one is from the ‘Get items’ and the second one from ‘Get items 2’. I can imagine that if you used twice the same dynamic content then it’d loop through all the items which could take a while.

      Reply
  10. Dobandoc says:
    July 23, 2022 at 9:49 pm

    Hi Tom,

    Your solutions have helped me a lot. I am a follower.
    I need help mixing up this solution a bit. I have a Sharepoint List with the values (from the email column), that sharepoint list is called: ‘Completed’.

    Email
    X5
    X2
    X4

    And a second Sharepoint List called ‘Users’ with all the emails of a company and a column called Exists.

    Email Exist
    X1 NO
    X2 YES
    X3 NO
    X4 YES
    X5 YES
    X6 NO

    If a user is added to the Sharepoint list named ‘Completed’, I want it to automatically search for that user in the Sharepoint list named ‘Users’ and update the ‘Exists’ column from NO to YES.

    I know that the initial trigger is: When an Item is created, but I am confused about the initialization of variables.

    Reply
    1. Tom says:
      July 26, 2022 at 10:07 pm

      Hello Dobandoc,
      I think this solution better describes your needs: https://tomriha.com/how-to-check-if-sharepoint-item-already-exists-in-power-automate/. Check if the email exists and if it does, update the item.

      Reply
  11. Dani says:
    September 28, 2022 at 10:26 pm

    Hello Tom, the first filter doesnt work, at least to me, it returns every value of my other list. Using my logic is because im searching one element in all the element of the other list, so when 1 is in the list the other 5 arent, so it returns those 5, and when the apply to each goes to the next element is the same.

    Reply
    1. Tom says:
      October 5, 2022 at 2:37 pm

      Hello Dani,
      I’d double check the filter if you’re using the right dynamic contents coming from the right actions as shown using the red arrows on the picture.

      Reply
  12. Soon says:
    January 9, 2023 at 3:06 pm

    Hi Tom:
    Happy New year!
    This is great! But if an item from the Source is not in the Target, the ‘Apply to each – Target List Item’ is greyed out and will not evaluate. How do I get the nested ‘Apply to each’ to evaluate blank outputs from the filter array?

    Reply
    1. Tom says:
      January 26, 2023 at 2:52 pm

      Hello Soon,
      ‘Apply to each’ will run only if there’re any values, otherwise it’ll be skipped. If you want to do something even if it returns no value you have to add a condition and check the result before going into the loop. For array you can use the length(…) > 0 expression as explained here: https://tomriha.com/what-value-to-use-in-condition-if-field-is-empty-in-power-automate/

      Reply
  13. walaa says:
    April 17, 2023 at 1:53 pm

    Hello Tom,

    Appreciate your support. The flow worked with me successfully but, after I applied the condition return true, I applied send email V2 action , It keeps sending emails frequently nonstop, there’s no additional ‘apply to each’ , just the two that you mentioned.

    Reply
    1. Tom says:
      May 1, 2023 at 3:45 pm

      Hello Walaa,
      you must find out why it’s sending emails? Is it some loop? Is it that the flow is triggered multiple times? Once you find the reason you can look for the solution.

      Reply
  14. Sharon says:
    November 24, 2023 at 12:16 pm

    Hi Tom,

    if I have list A with 10 items (consists unique identifier) and list B with 20 items (consists unique Identifier)
    How can I retrieve items from list B which are missing in list A?

    Also, I don’t need the list A to be updated but just need an email to be sent for the differences in the items in both the lists.

    any insight/help will be greatly appreciated.

    Thank you! 🙂

    Reply
  15. Moise says:
    September 12, 2024 at 10:43 pm

    Hallo Tom,

    1.are these Flow still updated with the changes MS did in Power Automate?
    2. how do i make the Flow to be reliable on more than 10.000 Records in the both Lists?
    Thanks!

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

🚀 Master Power Automate

Join 2,000+ professionals getting actionable Power Automate tutorials, solutions, cheat sheets & tips every week.

No spam. Unsubscribe anytime.

Still exchanging emails to get things approved?

Use the Approval Process Template and the Task Delegation App to skip the hard part and deploy an automated, fully functional approval solution on a SharePoint list in minutes! And then the next one, and the next one...

Approval Template Preview ✨ Learn more ✨

Turn ideas into flows with ease!

Grab the complete Power Automate Cheat Sheet Bundle—everything you need to master expressions, SharePoint HTTP calls, and Graph API in Power Automate.

Cheat Sheet Bundle Preview ✨ Get the Cheat Sheets

Didn't find what you were looking for?
Need to adjust a solution to fit your needs?
Or would you just like to get an assistance from somebody with thousands of hours of experience with Power Automate?

Power Automate blogs worth visiting

Damien Bird
Dennis (Expiscornovus)
Paul Murana

©2025 Let's POWER Automate | Theme by SuperbThemes