Sql 预测下一个记录的棘手问题
我正在做一个测试场景 每个站点6人Sql 预测下一个记录的棘手问题,sql,sql-server,Sql,Sql Server,我正在做一个测试场景 每个站点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:如果一个人在第一天测试了他的网站,那么他的轮到应该在第四天,而不是在那之前-只适用于本周。因此,如果A和D在22日测试A站点,B和E在23日测试,C和F在24日测试,那么本
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:如果一个人在第一天测试了他的网站,那么他的轮到应该在第四天,而不是在那之前-只适用于本周。因此,如果A和D在22日测试A站点,B和E在23日测试,C和F在24日测试,那么本周,A和D只能在25日测试站点。星期天是假日
规则2:每星期,这对情侣都应该换衣服。规则1仍然适用于新的一对
规则3:属于特定站点的人员不能测试其他站点
在查询中,我应该能够
后来换了两个人的一对
让他们一次三个人,或者
将每个站点上的人数从6人增加到10人
对代码的更改很少
样本数据
以下是我希望输出的方式:
等等
你能帮我查询一下吗
在查询中,我应该能够
后来换了两个人的一对
让他们一次三个人,或者
将每个站点上的人数从6人增加到10人
对代码的更改很少。我想要这种灵活性
这不是SQL要处理的事情。我肯定会把这种算法逻辑转换成代码
如果由于某种原因,你不能将它移动到代码中,并且绝对需要从数据库中获取预测信息,那么如果你使用MS SQL Server 2005或2008,我会在SQLServer中考虑CLR程序集。
通过嵌套循环和嵌入式查询,在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中都非常丑陋。用一种更通用的语言做这件事要容易得多。这在代码中会容易得多。。。我不明白你的意思是什么?你是说林克?你能告诉我怎么做吗。谢谢你。您将需要以下一个或多个:带有非平凡连接谓词的自连接、递归CTE、c排序函数、d datepart和dateadd函数。老实说,听起来像是一个家庭作业,有着武断的规则。
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
--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
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