我正在做一个测试场景
每个网站有6个人
Site 1 - A, B, C, D, E, F
Site 2 - G, H, I, J, K, L
Site 3 - M, N, O, P, Q, R
Site 4 - S, T, U, V, W, X
我想写一个查询,可以向我建议可以测试网站的人 - 一次两个。以下是规则:
规则1:如果某人在第1天测试了他的网站,那么轮到他们应该在第4天而不是在第4天之前 - 仅适用于当前周。因此,如果A和D在22日测试一个站点,B和E在23日测试它,在24日测试C和F测试,那么在本周,A和D只能在25日测试该站点。星期天是假期
规则2:每周,这一对都应该改变。规则1仍适用于新配对。
规则3:属于特定网站的人无法测试其他网站。
在查询中,我应该可以 后来改变了两人的对 并使他们一次3人或 将每个站点的人数从6增加到10,用 对代码进行了一些更改。
示例数据
DECLARE @Site TABLE
(
SiteID int,
SiteNm varchar(10)
)
DECLARE @Person TABLE
(
PersonID int,
PersonName char(1),
SiteID int
)
INSERT @Site
SELECT 1, 'Site1' UNION ALL
SELECT 2, 'Site2' UNION ALL
SELECT 3, 'Site3' UNION ALL
SELECT 4, 'Site4'
INSERT @Person
SELECT 1, 'A', 1 UNION ALL
SELECT 2, 'B', 1 UNION ALL
SELECT 3, 'C', 1 UNION ALL
SELECT 4, 'D', 1 UNION ALL
SELECT 5, 'E', 1 UNION ALL
SELECT 6, 'F', 1 UNION ALL
SELECT 7, 'G', 2 UNION ALL
SELECT 8, 'H', 2 UNION ALL
SELECT 9, 'I', 2 UNION ALL
SELECT 10, 'J', 2 UNION ALL
SELECT 11, 'K', 2 UNION ALL
SELECT 12, 'L', 2 UNION ALL
SELECT 13, 'M', 3 UNION ALL
SELECT 14, 'N', 3 UNION ALL
SELECT 15, 'O', 3 UNION ALL
SELECT 16, 'P', 3 UNION ALL
SELECT 17, 'Q', 3 UNION ALL
SELECT 18, 'R', 3 UNION ALL
SELECT 19, 'S', 4 UNION ALL
SELECT 20, 'T', 4 UNION ALL
SELECT 21, 'U', 4 UNION ALL
SELECT 22, 'V', 4 UNION ALL
SELECT 23, 'W', 4 UNION ALL
SELECT 24, 'X', 4
以下是我想要输出的方式:
Date Site 1 Site 2 Site 3 Site 4
22Jun A,D H,I N,R T,W
23Jun B,E J,K M,P V,X
...
26Jun A,D H,I N,R T,W
...
29Jun F,A K,L R,Q W,U
等等
你能帮我查询一下吗?
在查询中,我应该可以 后来改变了两人的对 并使他们一次3人或 将每个站点的人数从6增加到10,用 对代码的更改很少。我想要这种灵活性
答案 0 :(得分:2)
WITH sets AS
(
SELECT SiteID, SUBSTRING(CAST(PersonID AS VARCHAR(MAX)) + SPACE(8), 1, 8)AS result, 1 AS rn
FROM @Person p
UNION ALL
SELECT p2.SiteID, s.result + SUBSTRING(CAST(PersonID AS VARCHAR(MAX)) + SPACE(8), 1, 8), rn + 1
FROM sets s
JOIN @Person p2
ON p2.siteid = s.siteid
AND PATINDEX('%' + SUBSTRING(CAST(PersonID AS VARCHAR(MAX)) + SPACE(8), 1, 8) + '%', s.result) = 0
),
cal AS
(
SELECT 1 AS rn
UNION ALL
SELECT rn + 1
FROM cal
WHERE rn < 99
),
pairs AS
(
SELECT SiteId, result, ROW_NUMBER() OVER (PARTITION BY siteid ORDER BY rn2 % 30) pn
FROM (
SELECT s.*,
ROW_NUMBER() OVER (PARTITION BY siteid ORDER BY siteid) AS rn2
FROM sets s
WHERE rn = 6
) q
WHERE rn2 % 2 > 0
AND rn2 % 12 > 5
AND rn2 % 240 > 119
)
SELECT CAST('2009-01-01' AS DATETIME) + rn, siteid,
SUBSTRING(result, 1 + (rn % 3) * 16, 8) AS first,
SUBSTRING(result, 1 + (rn % 3) * 16 + 8, 8) AS second
FROM cal
JOIN pairs
ON pn = (rn / 7 + 1)
AND DATEPART(weekday, CAST('2009-01-01' AS DATETIME) + rn) <> 1
答案 1 :(得分:1)
这不是SQL要处理的内容。我绝对会将这种算法逻辑转移到代码中。
如果由于某种原因,您无法将其移动到代码中并且必须从数据库中获取预测信息,那么如果您使用的是MS SQL Server 2005或2008,我会考虑使用SqlSever中的CLR程序集。 / p>
答案 2 :(得分:0)
技术上可以通过嵌套循环和嵌入式查询在T-SQL中实现这一点。
--loop over sites
--loop over n-day periods (initially n=3, so day1->day4, discounting sundays)
-- loop over pairs in that period
--match people who are n+x IDs apart, x increments each n-day loop,
--need to mod this against count(persons per site)
-- end pairs loop
-- end n-day loop
-- end sites loop
T-SQL中的一切都非常难看。使用更通用的语言更容易做到这一点。