我有时会看到一篇有趣的帖子,但没有解决方案。试试运气:
有一个表包含10个名称(U1,U2,U3 ......等)。我必须每天选择5个名字,并显示一个作为编辑,4个作为贡献者
在选择随机名称时,我还必须考虑如果一个用户被选为编辑,他就不能再成为编辑,直到每个人都有机会。
输出应类似于以下内容:
Editor Cont1 Cont2 Cont3 Cont4
20-Jun U1 U8 U9 U3 U4
21-Jun U7 U2 U5 U6 U10
22-Jun U3 U4 U9 U2 U8
23-Jun U4 U8 U3 U5 U2
and so on..
答案 0 :(得分:2)
这种迁移是一种方法。最有可能的是,更短的版本是可能的,但输出似乎符合您的要求。
解决方案的要点如下
TOP 1
和NEWID()
从具有最低EditorCount的所有用户中选择一个随机用户,并更新该用户的EditorCount。SQL脚本
SET NOCOUNT ON
DECLARE @Users TABLE (
UserName VARCHAR(3)
, EditorCount INTEGER
, ContributorCount INTEGER
)
DECLARE @Solutions TABLE (
ID INTEGER IDENTITY(1, 1)
, Editor VARCHAR(3)
, Contributor1 VARCHAR(3)
, Contributor2 VARCHAR(3)
, Contributor3 VARCHAR(3)
, Contributor4 VARCHAR(3)
)
DECLARE @Editor VARCHAR(3)
DECLARE @Contributor1 VARCHAR(3)
DECLARE @Contributor2 VARCHAR(3)
DECLARE @Contributor3 VARCHAR(3)
DECLARE @Contributor4 VARCHAR(3)
INSERT INTO @Users
SELECT 'U1', 0, 0
UNION ALL SELECT 'U2', 0, 0
UNION ALL SELECT 'U3', 0, 0
UNION ALL SELECT 'U4', 0, 0
UNION ALL SELECT 'U5', 0, 0
UNION ALL SELECT 'U6', 0, 0
UNION ALL SELECT 'U7', 0, 0
UNION ALL SELECT 'U8', 0, 0
UNION ALL SELECT 'U9', 0, 0
UNION ALL SELECT 'U0', 0, 0
/* Keep Generating combinations until at least one user has been editor for 10 times */
WHILE NOT EXISTS (SELECT * FROM @Solutions WHERE ID = 30)
BEGIN
SELECT TOP 1 @Editor = u.UserName
FROM @Users u
INNER JOIN (
SELECT EditorCount = MIN(EditorCount)
FROM @Users
) ec ON ec.EditorCount = u.EditorCount
ORDER BY NEWID()
UPDATE @Users SET EditorCount = EditorCount + 1 WHERE UserName = @Editor
INSERT INTO @Solutions VALUES (@Editor, NULL, NULL, NULL, NULL)
SELECT TOP 1 @Contributor1 = u.UserName
FROM @Users u
INNER JOIN (
SELECT ContributorCount = MIN(ContributorCount)
FROM @Users
) ec ON ec.ContributorCount = u.ContributorCount
WHERE UserName <> @Editor
ORDER BY NEWID()
UPDATE @Users SET ContributorCount = ContributorCount + 1 WHERE UserName = @Contributor1
UPDATE @Solutions SET Contributor1 = @Contributor1 WHERE Contributor1 IS NULL
SELECT TOP 1 @Contributor2 = u.UserName
FROM @Users u
INNER JOIN (
SELECT ContributorCount = MIN(ContributorCount)
FROM @Users
) ec ON ec.ContributorCount = u.ContributorCount
WHERE UserName NOT IN (@Editor, @Contributor1)
ORDER BY NEWID()
UPDATE @Users SET ContributorCount = ContributorCount + 1 WHERE UserName = @Contributor2
UPDATE @Solutions SET Contributor2 = @Contributor2 WHERE Contributor2 IS NULL
SELECT TOP 1 @Contributor3 = u.UserName
FROM @Users u
INNER JOIN (
SELECT ContributorCount = MIN(ContributorCount)
FROM @Users
) ec ON ec.ContributorCount = u.ContributorCount
WHERE UserName NOT IN (@Editor, @Contributor1, @Contributor2)
ORDER BY NEWID()
UPDATE @Users SET ContributorCount = ContributorCount + 1 WHERE UserName = @Contributor3
UPDATE @Solutions SET Contributor3 = @Contributor3 WHERE Contributor3 IS NULL
SELECT TOP 1 @Contributor4 = u.UserName
FROM @Users u
INNER JOIN (
SELECT ContributorCount = MIN(ContributorCount)
FROM @Users
) ec ON ec.ContributorCount = u.ContributorCount
WHERE UserName NOT IN (@Editor, @Contributor1, @Contributor2, @Contributor3)
ORDER BY NEWID()
UPDATE @Users SET ContributorCount = ContributorCount + 1 WHERE UserName = @Contributor4
UPDATE @Solutions SET Contributor4 = @Contributor4 WHERE Contributor4 IS NULL
END
SELECT * FROM @Solutions
SELECT * FROM @Users
答案 1 :(得分:0)
这是一些伪C#代码。
假设你有两张桌子
1)用户表,其中包含所有用户
2) DailyTeam 表,其中包含每日选择的用户(您的输出)
struct Team
{
string name;
int editorCount;
}
currentEditorList is a List of Team
existingUserList is a List of Team
currentEditorList = Get Current Editor List from DailyTeam
existingUserList = Get All Users from User and its editor count (may need left outer join)
todayTeam is a new Array
// populate the normal users to dailyTeam
while (todayTeam count is less than 4)
{
randomIndex = generate a random number (from 0 to 9)
userName = get name from existingUserNames[randomIndex]
if (userName is not in todayTeam)
{
add userName to todayTeam
}
}
sort existingUserList by its editorCount
editorName = get the first item from existingUserList
add editorName to todayTeam
注意:我会在powershell中实现这个算法。
答案 2 :(得分:0)
这里让我解释一下我的解决方案,或者我应该说逻辑,因为我在不可以访问SQL Server的地方。 所以我无法对其进行测试,您可能需要进行编辑以使其正常运行。所以解释我的逻辑是什么..
首先假设您将在现有表中附加一列(这个逻辑必须为此逻辑),说“unirow”,它将具有唯一的编号 从1开始分配给每位员工。
然后yoy必须创建一个表tbl_counter,其中一列作为数字。只有一行(限制) 最初让它为1。
由于先决条件已经完成,现在让我们转向逻辑。我所做的就是五次为Employees表自我交叉加入 这样你就拥有了独特的团队组合。现在所有需要做的就是每次查询/程序时选择唯一的编辑器 被执行。此查询/过程的输出将包含5列第1列用于编辑器,其余用于贡献者。
BEGIN
DECLARE @counter number
DECLARE @limit number
DECLARE @Editor varchar(100)
select @limit=count(*) from Employees
select @counter=counter+1 from tbl_counter
IF(@counter>@limit)
begin
set @counter=1
update tbl_counter set counter=1
end
select @Editor=Name from Employees2 where id=@counter
select top 1 newid() as unirow,t1.name Editor,t2.name Contributor1,
t3.name Contributor2,t4.name Contributor3,t5.name Contributor4
from Employees t1,Employees t2,Employees t3,Employees t4,Employees t5
where t1.name<>t2.name and t1.name<>t3.name and t1.name<>t4.name and t1.name<>t5.name
and t2.name<>t1.name and t2.name<>t3.name and t2.name<>t4.name and t2.name<>t5.name
and t3.name<>t2.name and t3.name<>t1.name and t3.name<>t4.name and t3.name<>t5.name
and t4.name<>t2.name and t4.name<>t3.name and t4.name<>t1.name and t4.name<>t5.name
and t5.name<>t2.name and t5.name<>t3.name and t5.name<>t4.name and t5.name<>t1.name
and t1.name=@Editor
order by unirow
END