2010-06-17 109 views
1

我後來看到一篇有趣的文章,但沒有解決方案。在這裏嘗試運氣:挑選隨機名稱

有一張表,其中包含10個名稱(U1,U2,U3..and等等)。我必須每天選擇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

一是與約束而給出,編輯是不是隨機的。最初的順序是隨機的,但在一個週期後,它永遠不會改變。 其次,編輯也可以爲同一篇文章做貢獻嗎? – Slartibartfast 2010-06-17 05:10:46

+0

畢竟有10個用戶在編輯器上了,這個循環可能重新開始;循環N的最後編輯器也可以是循環N + 1中的第一個。從「選擇5並選擇1作爲編輯者,選擇4作爲貢獻者」這一點看起來很清楚,編輯者沒有被指定爲貢獻者。 – 2010-06-17 05:32:03

+0

是喬納森你是正確的..我需要一個SQL查詢相同 – Jasl 2010-06-17 06:13:47

回答

2

這個migth是一種方法來做到這一點。最有可能的是,更短的版本是可能的,但輸出似乎符合您的要求。

解決方案的要旨去如下

  • 爲每個用戶添加一個櫃檯,他有多少次,用戶已經編輯多少次是一個貢獻者。
  • 選擇使用TOP 1NEWID()NEWID()的所有用戶的一個隨機用戶並更新該用戶的EditorCount。
  • 同樣的貢獻者的選擇。從最低的ContributorCount的所有用戶中選擇一個隨機用戶,但不包括剛創建編輯器/撰稿人的用戶並更新該用戶的ContributeCount。

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 
+0

看起來不錯。很大的努力(+1)。我敢打賭,我無法說服你使用Powershell。 :p – Syd 2010-06-17 08:01:31

+1

我真的應該趕快用PowerShell ...有一天 2010-06-17 08:31:49

+1

我不知道該如何謝謝你..上帝保佑你和你的家人!這是我的整個團隊在 – Jasl 2010-06-17 10:20:48

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中實現這個算法。

0

這裏讓我解釋一下我的解決方案或者我應該說的邏輯,因爲我在那裏我切勿訪問SQL Server的一個地方。 所以我不能測試它,你可能必須編輯,使其工作。所以,解釋我的邏輯是什麼..

  • 首先假定你將在現有表追加列(這是必須爲這個邏輯)說:「unirow」的這將有一個唯一編號 分配給每個員工從1開始。

  • 然後,每年必須創建一個表tbl_counter與一列作爲數字。將只有一行(限制) 並且最初讓它爲1.

  • 由於先決條件已完成,現在讓我們轉到邏輯。我所做的只是爲員工表進行了五次自我交叉加入 ,以便您擁有團隊的獨特組合。現在,所有需要完成的是每次執行該查詢/過程 時選擇唯一的編輯器。此查詢/過程的輸出將包含編輯器的第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 [email protected] 
    
    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 [email protected] 
    order by unirow 
    

    END