如何从列生成随机数,没有重复 - SQL Server

时间:2013-07-04 14:45:42

标签: sql-server stored-procedures random while-loop no-duplicates

我有一个Profile表,其中包含以下列:UserIDFirstnameLastname

我正在尝试创建一个传入@UserID参数的存储过程,并生成从UserID列中获取的10个随机数。

这样做的目的是允许一个用户向10个随机用户发送消息(没有任何重复)

以下是我目前的情况:

CREATE PROCEDURE [dbo].[Random10]
@UserID INT
AS
DECLARE @MaxID INT, @MinID INT, @RandomID INT, @Index INT

SET @MinID = (SELECT MIN(P.UserID) FROM Profile P)
SET @MaxID = (SELECT MAX(P.UserID) FROM Profile P)
SET @Index = 0

CREATE TABLE #RandomUsers
(
ID INT PRIMARY KEY IDENTITY,
UserID INT
)


WHILE @Index < 10
BEGIN
    SELECT @RandomID = ROUND(((@MaxID - @MinID - 1) * RAND() + @MinID), 0)

    IF (@RandomID <> @UserID)
    BEGIN
        INSERT INTO #RandomUsers VALUES (@RandomID)
        SET @Index = @Index + 1
    END
ELSE
    BEGIN
        SET @Index = @Index
    END
END

SELECT * FROM #RandomUsers

我传入UserID'66'并使用'WHILE LOOP'和'RAND()'来生成10个数字。 'IF'语句用于消除'@UserID'参数出现在列表中(因为这将是发送消息的用户)

结果如下:

|ID|UserID|
| 1|    66|
| 2|    80|
| 3|    66|
| 4|    64|
| 5|    14|
| 6|    72|
| 7|    72|
| 8|    81|
| 9|    19|
|10|    56|

正如您所看到的,有一些重复。

我试图添加一个WHERE子句来消除这两个问题,但我得到一个返回的NULL集。

1 个答案:

答案 0 :(得分:3)

您可以尝试使用newid():

INSERT INTO #RandomUsers
Select TOP 10 userId From Profile WHERE userId <> @UserID
ORDER BY newid()

通过这种方式,您可以获得十个不同于您在参数中传递的用户。但我不知道如何在SQL Server中获得非常好的随机性。

编辑:

我认为您也可以使用tablesample()来解决这类问题,但我真的不知道如何使用它。

顺便说一下,如果id序列中出现了一个洞(就像删除了用户34那样),你仍然可以用你的方法选择34,而直接从表中取样的方法仍然有用。