Розыгрыш победителя лотерейного билета в T-SQL - PullRequest
1 голос
/ 28 июля 2011

У меня есть следующая таблица:

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 билеты были куплены.Бобу принадлежит ~ 58% билетов, Кэти ~ 38% и так далее:

SELECT [Name], Tickets / (SELECT SUM(Tickets) AS WinProb
FROM @TicketHolder) WinProb FROM @TicketHolder

Теперь мне нужно выбрать одного и только одного случайного победителя (достаточно RAND () достаточно) на основесколько билетов принадлежит каждому человекуСтрок может быть миллионы, поэтому зацикливание исключено.Как можно определить победителя с помощью T-SQL?

Ответы [ 2 ]

1 голос
/ 28 июля 2011

В этом запросе будет найдено случайное число на основе общего количества билетов:

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

Пример на данных SE. На данных SE, он всегда выбирает одного и того же победителя, возможно, потому что они фиксировали rand() фиксированным способом. Если я запускаю его локально, он работает нормально.

0 голосов
/ 28 июля 2011

Измените переменную таблицы, включив в нее столбец 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...