I'm struggling with a query which I feel should be straightforward but I just can't get my head around it.
We have a single table that holds relationships between different parties. The table SHOULD contain a row for each relationship. However, we've noticed that some relationships are missing and we want to rebuild those. Essentially there should be two rows per relationship, the relationship and the inverse.
So, a healthy table should look like this...
Id | PartyId | OtherPartyId | RelType | RelStatus
1 1111 2211 1 1
2 2211 1111 1 1
3 3344 4444 1 2
4 4444 3344 1 2
But, we have a situation like this...
Id | PartyId | OtherPartyId | RelType | RelStatus
1 1111 2211 1 1
2 2211 1111 1 1
3 3344 4444 1 2
4 5555 2224 1 2
5 2224 5555 1 2
The inverse of the relationship between party 3344 and 4444 is missing, so I want to return that row only so that I can insert the inverse relationship.
The 'id' column is immaterial as it is only an identity column, but RelType and RelStatus are important as these need to be the same for the inverse relationship - example being that there could be a relationship that DOES exist between 4444 and 3344 but it is of a different type and status so we should ignore that (unless of course it has a missing inverse too!).
I tried to create a composite key system to try and identify the missing rels but I found it brought back duplicates in some instances:
SELECT
CASE WHEN [PartyId] < [OtherPartyId]
THEN CAST([OtherPartyId] AS NVARCHAR(50)) + '.' + CAST([PartyId] AS NVARCHAR(50)) + '.' + CAST([RelType] AS NVARCHAR(50)) + '.' + CAST([RelStatus] AS NVARCHAR(50))
ELSE CAST([PartyId] AS NVARCHAR(50)) + '.' + CAST([OtherPartyId] AS NVARCHAR(50)) + '.' + CAST([RelType] AS NVARCHAR(50)) + '.' + CAST([RelStatus] AS NVARCHAR(50))
END AS CompKey
INTO #partyinvs
FROM PartyRelationships;
SELECT CompKey
FROM #partyinvs
GROUP BY CompKey
HAVING COUNT(*) < 2
I hope this makes sense?
Thanks, David