我有一组用户在可用于特定会议(插槽)时进行注册。我把它们相互映射,需要填写他们可以满足的第一个可用插槽,而无需双重预订。
我已经列举了一个例子,说明了我如何解决它,但我仍然坚持如何进一步发展。
CREATE TABLE #Slot (slot int, start datetime)
INSERT INTO #Slot VALUES (11, DATEADD(hour, 1, '1/1/1900 7:00:00'))
INSERT INTO #Slot VALUES (22, DATEADD(hour, 2, '1/1/1900 7:00:00'))
INSERT INTO #Slot VALUES (31, DATEADD(hour, 3, '1/1/1900 7:00:00'))
INSERT INTO #Slot VALUES (44, DATEADD(hour, 4, '1/1/1900 7:00:00'))
INSERT INTO #Slot VALUES (56, DATEADD(hour, 5, '1/1/1900 7:00:00'))
INSERT INTO #Slot VALUES (61, DATEADD(hour, 6, '1/1/1900 7:00:00'))
INSERT INTO #Slot VALUES (77, DATEADD(hour, 7, '1/1/1900 7:00:00'))
INSERT INTO #Slot VALUES (83, DATEADD(hour, 8, '1/1/1900 7:00:00'))
CREATE TABLE #Av (reg int, slot int)
INSERT INTO #Av
SELECT 1, slot
FROM #Slot
INSERT INTO #Av
SELECT 2, slot
FROM #Slot
INSERT INTO #Av
SELECT 3, slot
FROM #Slot
INSERT INTO #Av
SELECT 4, slot
FROM #Slot
CREATE TABLE #Met (reg1 int, reg2 int, slot int)
INSERT INTO #Met (reg1, reg2) VALUES (1, 2)
INSERT INTO #Met (reg1, reg2) VALUES (1, 3)
INSERT INTO #Met (reg1, reg2) VALUES (4, 2)
我最终使用以下CTE是他们可以满足的所有时间,但我不知道如何最终只有三行。我希望最终得到(使用提供的数据)是:
reg1 reg2 slot
1 2 11
1 3 22 --since 1 is meeting with 2 already in slot 11
4 2 22 --since 2 is meeting with 1 already in slot 11
到目前为止,这是我所拥有的...基本上所有选项,但不能归结为三行:
with poss(opt, r1, r2, slot) AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY m.reg1, m.reg2 ORDER BY s1.start),
m.reg1, m.reg2, s1.slot
FROM #Met m
INNER JOIN #Av r1 ON m.reg1 = r1.reg
INNER JOIN #Slot s1 ON r1.slot = s1.slot
INNER JOIN #Av r2 ON m.reg2 = r2.reg
INNER JOIN #Slot s2 ON r2.slot = s2.slot
WHERE r1.slot = r2.slot
)
SELECT
*
FROM poss e
INNER JOIN #met m ON e.r1 = m.reg1 AND e.r2 = m.reg2
ORDER BY opt
答案 0 :(得分:0)
这是我提出的一个有点迭代的过程:
with poss(opt, r1, r2, slot) AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY m.reg1, m.reg2 ORDER BY s1.start),
m.reg1, m.reg2, s1.slot
FROM #Met m
INNER JOIN #Av r1 ON m.reg1 = r1.reg
INNER JOIN #Slot s1 ON r1.slot = s1.slot
INNER JOIN #Av r2 ON m.reg2 = r2.reg
INNER JOIN #Slot s2 ON r2.slot = s2.slot
WHERE r1.slot = r2.slot
)
, cs as (
SELECT
reg1, reg2, e.slot
, cr=checksum(reg1,reg2)
, cs1=checksum(reg1,e.slot)
, cs2=checksum(reg2,e.slot)
, rn=row_number()over(order by e.slot,reg1,reg2)
FROM poss e
INNER JOIN #met m ON e.r1 = m.reg1 AND e.r2 = m.reg2
)
select *
into #poss
from cs
order by rn
go
select top 0 * into #poss1 --this will hold the final results
from #poss
declare @i int=1;
while @i <= (select count(*) from #Met) begin
insert into #poss1
select * from #poss p
where not exists(select 1 from #poss (nolock) where (cr=p.cr or cs1=p.cs1 or cs2=p.cs2) and rn<p.rn)
and p.rn=@i
order by slot, reg1, reg2
set @i+=1;
end;
while @i <= (select count(*) from #poss) begin
insert into #poss1
select * from #poss p
where not exists(select 1 from #poss1 (nolock) where (cr=p.cr or cs1=p.cs1 or cs2=p.cs2))
and p.rn=@i;
set @i+=1;
end;
go
select reg1, reg2, slot from #poss1
go
结果: