获取那些与另一个表中所有记录匹配的记录
在这个问题的范围内,我有3个实体:
User
Position
License
然后我有两个关系(多对多)表:
PositionLicense
- 这个连接Position
和License
ie。特定职位需要哪些许可证
UserLicense
- 这个连接User
和License
ie。授予特定用户的许可。但附加复杂:用户许可证的有效日期范围(ValidFrom
和ValidTo
)
问题
这些是输入变量:
UserID
标识特定的User
RangeFrom
定义了较低的日期范围限制
RangeTo
定义了上限日期范围
我需要得到什么?对于特定用户(和日期范围),我需要获取此特定用户可以使用的职位列表。问题是用户必须至少拥有每个匹配位置所需的所有许可证。
我在编写SQL查询以获取此列表时遇到了很大的问题。
如果可能的话我想使用单个SQL查询(当然可以有其他CTE)。如果你能说服我在几个查询中这样做会更有效率我愿意听。
一些可行的数据
复制并运行此脚本。 3个用户,3个职位,6个许可证。马克和约翰应该有比赛而不是简。
create table [User] (
UserID int identity not null
primary key,
Name nvarchar(100) not null
)
go
create table Position (
PositionID int identity not null
primary key,
Name nvarchar(100) not null
)
go
create table License (
LicenseID int identity not null
primary key,
Name nvarchar(100) not null
)
go
create table UserLicense (
UserID int not null
references [User](UserID),
LicenseID int not null
references License(LicenseID),
ValidFrom date not null,
ValidTo date not null,
check (ValidFrom < ValidTo),
primary key (UserID, LicenseID)
)
go
create table PositionLicense (
PositionID int not null
references Position(PositionID),
LicenseID int not null
references License(LicenseID),
primary key (PositionID, LicenseID)
)
go
insert [User] (Name) values ('Mark the mechanic');
insert [User] (Name) values ('John the pilot');
insert [User] (Name) values ('Jane only has arts PhD but not medical.');
insert Position (Name) values ('Mechanic');
insert Position (Name) values ('Pilot');
insert Position (Name) values ('Doctor');
insert License (Name) values ('Mecha');
insert License (Name) values ('Flying');
insert License (Name) values ('Medicine');
insert License (Name) values ('PhD');
insert License (Name) values ('Phycho');
insert License (Name) values ('Arts');
insert PositionLicense (PositionID, LicenseID) values (1, 1);
insert PositionLicense (PositionID, LicenseID) values (2, 2);
insert PositionLicense (PositionID, LicenseID) values (2, 5);
insert PositionLicense (PositionID, LicenseID) values (3, 3);
insert PositionLicense (PositionID, LicenseID) values (3, 4);
insert UserLicense (UserID, LicenseID, ValidFrom, ValidTo) values (1, 1, '20110101', '20120101');
insert UserLicense (UserID, LicenseID, ValidFrom, ValidTo) values (2, 2, '20110101', '20120101');
insert UserLicense (UserID, LicenseID, ValidFrom, ValidTo) values (2, 5, '20110101', '20120101');
insert UserLicense (UserID, LicenseID, ValidFrom, ValidTo) values (3, 4, '20110101', '20120101');
insert UserLicense (UserID, LicenseID, ValidFrom, ValidTo) values (3, 6, '20110101', '20120101');
得到的解决方案
我根据已接受的答案设置了我的最终解决方案,为此问题提供了最简化的解决方案。如果你想玩查询只需点击编辑/克隆(无论你是否登录)。什么可以改变:
三个变量:
两个变量来设置日期范围(@From
和@To
)
用户名(@User
)
您可以在第一个CTE中切换注释代码,以在完全重叠的用户许可证或部分重叠的用户许可证之间切换代码。
没有找到相关结果
已邀请:
3 个回复
疾桓
没有数据所以我无法调试或测试它,但是这个或非常接近它的东西应该可以解决问题。
播匣扦阔食
如果要求您希望用户和位置在整个范围内有效,那就更棘手了:
弦砂牧扁
您可以将其转换为在生效日期参数化的内联表值函数。