HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Return number of rows based on column value

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
rowsnumbercolumnreturnvaluebased

Problem

We are administering a sweepstakes for a client where we have a GUID tied to a contestant and the number of entries the contestant has acquired. I want to be able to draw winners based on the chance of winning corresponding to the number of entries.

GUID | Entries
--------------
1    | 1
2    | 5
3    | 2
4    | 7


So the results would be:

GUID
----
1
2
2
2
2
2
3
3
4
4
4
4
4
4
4


Basically I plan put the results in a spreadsheet and then use a random number generator to pick a row number between 1 and n, where n is the total number of entries. But of course if there is a way to easily select the winner programmatically, I'm all ears (or eyes as the case may be).

Thanks in advance.

Solution

For interest's sake, here is a solution for SQL Server 2016 that uses the built-in [pseudo]random number generator to pick a winner for you.

First, the data:

CREATE TABLE #t
(ID int,
Entries int)

INSERT #t
VALUES
(1,1),
(2,5),
(3,2),
(4,7)


Then the code:

DECLARE @r float = RAND()

SELECT TOP 1 ID, @r
FROM (
    SELECT ID,
    Entries,
    SUM(Entries) OVER(ORDER BY ID) / CONVERT(float,SUM(Entries) OVER()) AS RunningFraction
    FROM #t
) RF
WHERE RunningFraction > @r
ORDER BY ID


You can skip the variable declaration and just use WHERE RunningFraction > RAND(), but this format makes it easier to test the functionality.

Code Snippets

CREATE TABLE #t
(ID int,
Entries int)

INSERT #t
VALUES
(1,1),
(2,5),
(3,2),
(4,7)
DECLARE @r float = RAND()

SELECT TOP 1 ID, @r
FROM (
    SELECT ID,
    Entries,
    SUM(Entries) OVER(ORDER BY ID) / CONVERT(float,SUM(Entries) OVER()) AS RunningFraction
    FROM #t
) RF
WHERE RunningFraction > @r
ORDER BY ID

Context

StackExchange Database Administrators Q#159462, answer score: 5

Revisions (0)

No revisions yet.