I have Users, Positions and Licenses.
Relations are:
- users may have many licenses
- positions may require many licenses
So I can easily get license requirements per position(s) as well as effective licenses per user(s).
But I wonder what would be the best way to match the two sets? As logic goes user needs at least those licenses that are required by a certain position. May have more, but remaining are not relevant.
I would like to get results with users and eligible positions.
PersonID PositionID
1 1 -> user 1 is eligible to work on position 1
1 2 -> user 1 is eligible to work on position 2
2 1 -> user 2 is eligible to work on position 1
3 2 -> user 3 is eligible to work on position 2
4 ...
As you can see I need a result for all users, not a single one per call, which would make things much much easier.
There are actually 5 tables here:
create table Person ( PersonID, ...)
create table Position (PositionID, ...)
create table License (LicenseID, ...)
and relations
create table PersonLicense (PersonID, LicenseID, ...)
create table PositionLicense (PositionID, LicenseID, ...)
So basically I need to find positions that a particular person is licensed to work on. There’s of course a much more complex problem here, because there are other factors, but the main objective is the same:
How do I match multiple records of one relational table to multiple records of the other. This could as well be described as an inner join per set of records and not per single record as it’s usually done in TSQL.
I’m thinking of TSQL language constructs:
- rowsets but I’ve never used them before and don’t know how to use them anyway
intersectstatements maybe although these probably only work over whole sets and not groups
Final solution (for future reference)
In the meantime while you fellow developers answered my question, this is something I came up with and uses CTEs and partitioning which can of course be used on SQL Server 2008 R2. I’ve never used result partitioning before so I had to learn something new (which is a plus altogether). Here’s the code:
So I made a comparison between these three techniques that I named as:
Mine already orders results per person and position, so I also added the same to the other two to make return identical results.
Resulting estimated execution plan
I also changed Table variable version into a CTE version (instead of table variable a CTE was used) and removed
order byat the end and compared their estimated execution plans. Just for reference CTE version 43% while original version had 53% (10% + 43%).