我有一个Profile
表,其中包含以下列:UserID
,Firstname
,Lastname
我正在尝试创建一个传入@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集。
答案 0 :(得分:3)
您可以尝试使用newid():
INSERT INTO #RandomUsers
Select TOP 10 userId From Profile WHERE userId <> @UserID
ORDER BY newid()
通过这种方式,您可以获得十个不同于您在参数中传递的用户。但我不知道如何在SQL Server中获得非常好的随机性。
编辑:
我认为您也可以使用tablesample()来解决这类问题,但我真的不知道如何使用它。
顺便说一下,如果id序列中出现了一个洞(就像删除了用户34那样),你仍然可以用你的方法选择34,而直接从表中取样的方法仍然有用。