Выбор случайных имен - PullRequest
       3

Выбор случайных имен

1 голос
/ 17 июня 2010

Я видел интересный пост некоторое время назад, но без решения.Здесь можно попытать счастья:

Есть таблица, которая содержит 10 имен (U1, U2, U3 и т. Д.).Мне приходится ежедневно выбирать 5 имен и отображать одно в качестве редактора, а четыре - в качестве авторов

При выборе случайных имен я также должен учитывать, что если один пользователь выбран в качестве редактора, он не может снова стать редактором докаждый получил свой шанс.

Вывод должен выглядеть примерно так:

           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..

Ответы [ 3 ]

2 голосов
/ 17 июня 2010

Этот миг будет одним из способов сделать это. Скорее всего, более короткие версии возможны, но вывод соответствует вашим требованиям.

Суть решения выглядит следующим образом

  • Добавьте счетчик для каждого пользователя, сколько раз пользователь был редактором и сколько раз он был автором.
  • Выберите один случайный пользователь из всех пользователей с наименьшим значением EditorCount, используя TOP 1 и NEWID(), и обновите EditorCount этого пользователя.
  • Аналогично, выбор (ы) для авторов. Выберите один случайный пользователь из всех пользователей с наименьшим ContributorCount, за исключением пользователей, которые только что стали редактором / вкладчиком, и обновите 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
0 голосов
/ 17 июня 2010

Здесь позвольте мне объяснить мое решение, или я должен сказать логику, потому что я нахожусь в месте, где у меня НЕ есть доступ к SQL Server.Так что я не могу проверить это, вам, возможно, придется отредактировать, чтобы оно заработало .Объясняя, в чем моя логика ..

Прежде всего, при условии, что вы добавите столбец (который ДОЛЖЕН БЫТЬ для этой логики) в существующей таблице, скажите «unirow», который будет иметь уникальный номер, назначенный каждому сотруднику, начиная с 1.

Тогда вам нужно создать таблицу tbl_counter с одним столбцом в качестве числа. Будет только одна строка (ограничение), и изначально она будет равна 1.

Поскольку предварительное условие завершено, теперь давайте перейдем к логике.Все, что я сделал, - это сделал сам кросс-соединение для таблицы сотрудников пять раз, чтобы у вас была уникальная комбинация команды.Теперь все, что нужно сделать, это выбрать уникальных редакторов при каждом выполнении этого запроса / процедуры.Выходные данные этого запроса / процедуры будут содержать 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

0 голосов
/ 17 июня 2010

Вот некоторый псевдо-код 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...