Skip to main content

Hi everyone,

I'm facing an issue with how Celonis handles many-to-many (N:N) relationships. It seems like Celonis treats these relationships as 1:N → 1:N instead of supporting 0:N → 0:N, which leads to missing data when filtering.

Example Issue:

I have a many-to-many relationship between contracts and assets, modeled with an intermediate table:

Contract Asset
C1 A2
C2 A1
C3 NULL
C4 NULL
NULL A3
NULL A4

The issue occurs when I apply a filter like "Asset ≠ A4". Instead of just removing A4, I also lose contracts C3 and C4, which should still be visible since they are not linked to any asset.

My Understanding of the Issue:

  • Celonis seems to implicitly treat N:N relationships as 1:N → 1:N, enforcing a strict link between contracts and assets.
  • It does not seem to support a true N:N model, where both sides can have optional (0:N) relationships.

Question:

Has anyone faced this issue before?
Is there a recommended modeling approach to ensure that filtering on assets does not remove unrelated contracts?

Thanks in advance! 😊

Hi ​@maxime.psbpm,

Indeed, Celonis does not natively support 0:N → 0:N modeling, Celonis treats N:N as 1:N → 1:N, which can cause unintended data loss when filtering. This is because the default filtering logic in Celonis are INNER JOINS, where only matching records remain.

So in your case, This means contracts that do not have a linked asset get unintentionally filtered out.

To avoid losing unrelated contracts, in the past I modeled the assets in a separate table instead of relying solely on an intermediate table.

Your asset table would be something like this.


SELECT DISTINCT Asset 
FROM CONTRACT_ASSET 
WHERE Asset IS NOT NULL;


This table would then contain only the assets, without the link to contracts.


And then you would have to Modify your contract_asset table to ensure there are only valid links.

 

This ensures:

  • Only actual contract-asset links exist in the join table
  • Contracts without assets are handled separately.

In the end, you can apply the filtering on assets, not contract_assets. this ensures C3 and C4 aremain in the dataset because we didn’t filter them out through Celonis’ default INNER JOIN.

 

This is pretty hard to explain textually, apologies. If you need some more help, let me know.


Reply