【问题标题】:Unique Top 5 Random Query唯一的 Top 5 随机查询
【发布时间】:2014-10-20 04:55:48
【问题描述】:

假设我有一个应用程序可以确定抽奖中的获胜者。所有条目都输入到一个表中,表明它们的员工 ID。每个员工可以多次进入图纸。我从表中选择,按 newid 排序以获得随机排序。我假设员工的条目(数据库记录)越多,每次运行它时,他就有更好的机会进入我的查询的前 5 名。到目前为止,一切都很好。但是,由于每个员工都有多条记录,他很有可能会多次进入前 5 名。我需要能够从随机排序的结果中返回 5 条唯一记录。

如何获得 5 个唯一行,同时仍确保具有多个绘图条目的行在选择中获得更大的权重?

我的基本查询:

SELECT TOP 5 employeeID
 FROM events 
   TABLESAMPLE(1000 ROWS) 
 ORDER BY CHECKSUM(NEWID());

有点像我正在尝试做的事情:

SELECT TOP 5 *
    FROM events 
    WHERE employeeID IN (SELECT employeeID
     FROM events 
       TABLESAMPLE(1000 ROWS) 
     ORDER BY CHECKSUM(NEWID())
     )
 ORDER BY CHECKSUM(NEWID())

但我当然不能在子查询中进行排序。

【问题讨论】:

  • multiple drawing entries get a heavier weightin 听起来不像是随机选择吧?
  • 如果您将其视为员工将票根放入绘图桶中。对于我投入的每张票,我都有机会获胜。问题是,一旦我赢得了 5 个奖项中的一个,我就没有资格赢得任何其他奖项。你可以这样看,一旦我的名字被抽中,就删除我所有的其他票。
  • 我想我可以获取前 1 个员工 ID,将其添加到临时表并再次选择。如果临时表中不存在下一个选定的employeeID,则仅添加它。但我怀疑有一种更清洁的方法。

标签: sql sql-server tsql sorting


【解决方案1】:

任何解决方案都必须考虑两件事:

  • 如果员工输入多张彩票,他的中奖机会相对于其他人增加。
  • 每个人只能赢一次

这是我的方法:

;WITH
    tmp1 AS
    (
        SELECT      EmployeeID,
                    ROW_NUMBER() OVER (ORDER BY NEWID()) AS SortOrder
        FROM        Events
    ),
    tmp2 AS
    (
        SELECT      EmployeeID,
                    MIN(SortOrder) AS WinOrder
        FROM        tmp1
        GROUP BY    EmployeeID
    )


SELECT TOP 5 *
FROM tmp2
ORDER BY WinOrder

SQL Fiddle 给员工 1 和 5 更高的获胜机会,但无论他们进入多少次,他们都只能获胜一次。

【讨论】:

  • 我倾向于这种解决方案。到目前为止,它似乎工作得很好。您上面的描述很好地说明了这个问题,我自己说得再好不过了。
【解决方案2】:

这里有一个相当简单的方法来获得你想要的东西:

select top 5 EmployeeID
from
(
    select EmployeeID, row_number() over (order by newid()) DrawOrder
    from Events
) wins
group by EmployeeID
order by min(DrawOrder)

【讨论】:

    猜你喜欢
    • 2014-03-25
    • 2010-10-10
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-05
    相关资源
    最近更新 更多