I’ve not had any luck searching for a solution to this, partly because I’m not exactly sure how best to explain the problem! Hopefully I’m clear here but if not please feel free to ask for more info.
At the top level:
In our database, each customer can have multiple services. Services are allocated to a customer individually. However, we need ‘group’ services into ‘packages’ of common service combinations for reporting purposes.
I have a database which contains package definitions – a table called packageServices, simply listing each PackageID with an associated ServiceID. Therefore I can retrieve a list of services for each package.
From the same database I can retrieve a list of ServiceIDs for a particular customer.
What I am trying to accomplish is to compare the list of ServiceIDs retrieved for that customer, and see if that combination matches any of the defined pacakges (i.e. combinations of ServiceIDs) and if so report which package(s) that customer has.
I’m struggling to know where to begin so far as the comparison goes! I guess I need to start by creating some sort of list of serviceIDs for each package (rather than my current KeyValuePairs (in the dictionary) with multiple lines for each package?) then iterate through the packages and compare those lists of services with the list of services that customer has?
The data types used here may not be most appropriate – in many cases I’m referring to a ‘logical’ list rather than a C# List object – I can use whichever datatype is appropriate 🙂
Any help much appreciated!
EDIT – It’s been suggested that I collate this information in SQL instead of in my C# application. This seems like a good idea and one of the answers below has brought me close. However, there are ‘business rules’ in place which determine whether a package is an ‘upgrade’ of a lower package or a package in itself and this is seriously complicating things.
The more I try to make this work the more I think that I’ve bitten off more than I can chew! I am trying to design this properly, so that any changes to services or packages in the future will be handled easily – these changes are unlikely but possible. However, it would be much easier to just to hardcode the options from what I’ve seen so far!
EDIT 2 – I’ve been working through this and it has been suggested that I assign a ‘weight’ and a ‘group’ to each package. The groups are there to ensure that a customer can only have one package from each group, and the weights are there to ensure that only the ‘highest’ level package is returned. Using this in conjunction with @MarceloCantos ‘s query will mean that I should be able to return just the ‘highest’ weight package from each group – this looks like it might fit the requirements of the application!
Thanks to all who have helped so far – I’m amazed how quickly the responses started coming in and at the quality of the responses given. I’ll give this a go and see how I get on.
You can count the services for the customer and then, for each package that has the same number of services, count the services that match the customer’s services. Only an exact match will yield the same count.
You can do this in a single query, albeit a rather tricksy one:
EDIT: Perhaps I misunderstood the question. If you want to find packages that contain a subset of the customer’s services, you can do this instead:
EDIT 2: I changed the logic of the second case to exploit the fact that if the intersection of two sets is the same size as the smaller set, then the smaller set is a subset of the larger.