在随机选择中限制记录

3

我已经搜索了很多地方,但似乎无法找到答案,所以我需要帮助。

我正在尝试随机选择5个人。就像一次抽奖。每个人都可以自由报名参加,但只有其中的3次报名才会被考虑。因此...将选出5个不同的获胜者,但所有的报名(包括重复的)都需要被考虑,最多只能算3次报名。

例如:

Adam,1
Adam,2
Adam,1
Adam,1
Sally,2
Timmy,3
John,1
John,1
Jenny,2
Wendy,3
Wendy,3
Wendy,3
Wendy,5
Wendy,5

以下是我到目前为止的代码:

select top 5 
    name, vote 
from 
    (SELECT 
         name, vote 
     FROM 
         Entries 
     GROUP BY 
          name, vote) winners 
ORDER BY
    NEWID();

我的问题是(1)我不知道如何将它们限制为每个考虑三次,因为我想不起来该怎么做;(2)使用Distinct不起作用,因为他们可以输入100次并且每次都对不同的条目进行投票。


1
vote 代表什么? - Hart CO
1
你正在使用哪个版本的SQL Server? - Gordon Linoff
@user3361687,您能解释一下vote代表什么吗?您正在按名称和投票进行分组,是“Wendy”有3个条目可以获胜,即使她在其中5次,还是“Wendy,5”有2次获胜机会,因为她在其中2次? - Hart CO
为什么要使用已经退役的14年老产品? - abatishchev
票数无关紧要。如果她赢了,奖品是她想要的。她的五个条目都将被计算。她的投票对她的获胜没有影响。 - KylieM
显示剩余2条评论
3个回答

1

试试这个。它只会包含每个名称最多三个条目。

WITH UpToThree AS
(
    SELECT
         Name
        ,RN = ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Vote)
        ,NEWID() as RandID
    FROM
        Entries
)
SELECT TOP 5
    Name, MAX(RandID)
FROM
    UpToThree
WHERE
    RN < 4
GROUP BY
    Name
ORDER BY
    MAX(RandID)

但这会使参赛者的投票产生偏见 - 在温迪的情况下,她的“5”票将不被视为她的前三票是“3”。 - user2864740
这并不会阻止同一个人被多次选择。 - Hart CO
@user2864740 我没有意识到这是投票列中的投票计数。如果是的话,那么这个表格还有其他问题... - JNK
现在它出问题了。在使用DISTINCT时,无法按NEWID()排序而不选择NEWID() - Hart CO
投票结果并不重要,我只是在获胜者列表中展示它们。 :) - KylieM
@JNK...聪明的解决方案。然而,我认为从随机数中取最大值并不会使拥有三个条目的人比只有一个条目的人赢得胜利的可能性增加三倍。它会给他们更好的机会,但我不认为这是线性的。 - Gordon Linoff

1

我不确定以下任何一项在SQL 2000中是否不可用:

SELECT TOP 5 Name
FROM (SELECT Name,ABS(CHECKSUM(NEWID())) nid, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY NEWID()) RN
      FROM Table1) as sub
WHERE RN <= 3
GROUP BY Name
ORDER BY MAX(nid)

演示: SQL Fiddle

我不确定您希望如何决定要显示哪个投票,但如果您希望仅根据名称考虑条目,则应在与获胜者列表的单独连接中处理。


是的...我收到了“ROW_NUMBER”不是一个被识别的函数名的错误。不过我发现可以使用临时表来完成同样的操作。我会进行调查的。也许这个查询可能无法编写。感谢大家的帮助! - KylieM

0

我认为确保拥有3个条目的人比只有1个条目的人更有3倍的获胜机会是一项挑战。我假设votes不重要,因为在问题或评论中没有提到。

策略是首先使用row_number()(和where)随机限制每个人的条目数为3。然后,再次对结果进行排序,并使用row_number()随机枚举每行。通过随机枚举,任何条目都有相等的机会位于顶部--因此,拥有3个条目的人有三倍的概率成为最佳人选,而不是只有一个条目的人。

最后,根据这个序列号选择前五个人:

with entries_3 as (
      select e.*
      from (select e.*, row_number() over (partition by name order by newid()) as seqnum
            from entries
           ) e
      where seqnum <= 3
     ),
     entries_3_ordered (
      select e.*, row_number() over (order by newid()) as seqnum2
      from entries_3
     )
select top 5 name, votes
from from entries_3_ordered
group by name, votes
order by min(seqnum2);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接