我有下表:
DECLARE @TicketHolder TABLE
(
[Name] VARCHAR(100),
Tickets DECIMAL(18, 8)
);
有一些测试值:
INSERT INTO @TicketHolder ([Name], Tickets)
SELECT 'Bob', 10.37
UNION ALL
SELECT 'Lisa', 1
UNION ALL
SELECT 'Robbie', 150.981
UNION ALL
SELECT 'Cathy', 97.888531;
已购买260.239531张门票。 Bob拥有约58%的门票,Cathy约占38%,依此类推:
SELECT [Name], Tickets / (SELECT SUM(Tickets) AS WinProb
FROM @TicketHolder) WinProb FROM @TicketHolder
现在,我需要根据每个人拥有的票数选择一个且只有一个随机赢家(使用RAND()就足够了)。可能有数百万行,因此循环是不可能的。如何使用T-SQL绘制胜利者?
答案 0 :(得分:1)
此查询会根据票证总数找到一个随机数:
rand() * (select sum(tickets) from @TicketHolder)
您可以将其与运行总和查询结合使用,以查找绘制随机数的块的所有者:
select top 1 t1.Name
from @TicketHolder t1
where (
select sum(Tickets)
from @TicketHolder t2
where t2.Name <= t1.Name
) > rand() * (select sum(tickets) from @TicketHolder)
order by
t1.Name
Example at SE Data.在SE数据上,它总是选择相同的获胜者,可能是因为他们以固定方式播种rand()
。如果我在本地运行它,它可以正常工作。
答案 1 :(得分:0)
修改您的表变量以包含RunningCount列:
DECLARE @TicketHolder TABLE (
[Name] VARCHAR(100),
Tickets DECIMAL(18, 8),
RunningCount decimal(18,8)
);
添加票证数据:
INSERT INTO @TicketHolder ([Name], Tickets)
SELECT 'Bob', 10.37
UNION ALL
SELECT 'Lisa', 1
UNION ALL
SELECT 'Robbie', 150.981
UNION ALL
SELECT 'Cathy', 97.888531;
构建所有已购买门票的总计,并使用计数更新表格:
declare @RunningCount decimal(18,8) = 0
update @TicketHolder
set
@RunningCount = @RunningCount + Tickets,
RunningCount = @RunningCount
计算中奖彩票号
declare @WinningCount decimal(18,8) = @RunningCount * rand()
选择获胜者:
select top 1
@WinningCount,
Name
from
@TicketHolder
where
RunningCount <= @WinningCount
order by
RunningCount desc