This migth be one way to do it. Most likely, shorter versions are possible but the output seem to match your requirements.
The gist of the solution goes as follows
- Add a counter for every user for how many times a user has been an editor and how many times he has been a contributor.
- Select one random user from all users with the lowest EditorCount using a
TOP 1
and NEWID()
and update that user's EditorCount.
- Likewise the selection(s) for contributors. Select one random user from all users with the lowest ContributorCount, excluding users who just been made editor/contributor and update that user's ContributeCount.
SQL Script
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