Сценарий тотализаторов TSQL - PullRequest
       12

Сценарий тотализаторов TSQL

4 голосов
/ 28 октября 2009

Мне нужно запустить скрипт лотереи, чтобы получить X победителей из таблицы клиентов. Каждый клиент имеет N участников. Таблица выглядит так

ЗАКАЗЧИК-А 5

ЗАКАЗЧИК-Б 8

CUSTOMER-C 1

Я всегда могу написать сценарий, чтобы CUSTOMER-A, B и C вставлялись 5, 8 и 1 раз соответственно в временную таблицу, а затем выбирались случайным образом, используя order by newid(), но хотелось бы знать, есть ли более элегантный способ решения этой .

Ответы [ 2 ]

1 голос
/ 29 октября 2009

(Обновление: добавлен окончательный запрос.)
(Обновление 2: добавлен один запрос, чтобы избежать временной таблицы.)

Вот сложная часть с использованием рекурсивного CTE плюс окончательный запрос, показывающий «место».

код

DECLARE @cust TABLE (
    CustomerID      int     IDENTITY,
    ParticipationCt int
)

DECLARE @list TABLE (
    CustomerID      int,
    RowNumber       int
)

INSERT INTO @cust (ParticipationCt) VALUES (5)
INSERT INTO @cust (ParticipationCt) VALUES (8)
INSERT INTO @cust (ParticipationCt) VALUES (1)
INSERT INTO @cust (ParticipationCt) VALUES (3)
INSERT INTO @cust (ParticipationCt) VALUES (4)

SELECT * FROM @cust

;WITH t AS (
    SELECT
        lvl = 1,
        CustomerID,
        ParticipationCt
    FROM @Cust

    UNION ALL

    SELECT
        lvl = lvl + 1,
        CustomerID,
        ParticipationCt
    FROM t
    WHERE lvl < ParticipationCt
)
INSERT INTO @list (CustomerID, RowNumber)
SELECT
    CustomerID,
    ROW_NUMBER() OVER (ORDER BY NEWID())
FROM t

--<< All rows
SELECT * FROM @list ORDER BY RowNumber

--<< All customers by "place"
SELECT
    CustomerID,
    ROW_NUMBER() OVER (ORDER BY MIN(RowNumber)) AS Place
FROM @list
GROUP BY CustomerID

Результаты

 CustomerID ParticipationCt
----------- ---------------
          1               5
          2               8
          3               1
          4               3
          5               4

 CustomerID   RowNumber
----------- -----------
          4           1
          1           2
          1           3
          2           4
          1           5
          5           6
          2           7
          2           8
          4           9
          2          10
          2          11
          2          12
          1          13
          5          14
          5          15
          3          16
          5          17
          1          18
          2          19
          2          20
          4          21

 CustomerID Place
----------- -----
          4     1
          1     2
          2     3
          5     4
          3     5

Одиночный запрос без временной таблицы

Возможно получить ответ с помощью одного запроса, который не использует временную таблицу. Это прекрасно работает, но мне лично больше нравится версия временного стола, чтобы вы могли проверить промежуточные результаты.

Код (одиночный запрос)

;WITH List AS (
    SELECT
        lvl = 1,
        CustomerID,
        ParticipationCt
    FROM @Cust

    UNION ALL

    SELECT
        lvl = lvl + 1,
        CustomerID,
        ParticipationCt
    FROM List
    WHERE lvl < ParticipationCt
),
RandomOrder AS (
    SELECT
        CustomerID,
        ROW_NUMBER() OVER (ORDER BY NEWID()) AS RowNumber
    FROM List
)
SELECT
    CustomerID,
    ROW_NUMBER() OVER (ORDER BY MIN(RowNumber)) AS Place
FROM RandomOrder
GROUP BY CustomerID
1 голос
/ 28 октября 2009

попробуйте это:

   Select Top X CustomerId
   From (Select CustomerId,
         Rand(CustomerId) *
            Count(*) / 
              (Select Count(*) 
               From Table) Sort
         From Table
         Group By CustomerId) Z
   Order By Sort Desc

РЕДАКТИРОВАТЬ: abovbe предполагает наличие нескольких строк для каждого клиента, по одной строке для каждого участника.

Select Top 23 CustomerId
From ( Select  CustomerId,
        Participations - RAND(CustomerId) * 
         (Select SUM(Participations ) From customers) sort
       from customers) Z
Order By sort  desc   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...