2013-03-21 4 views
4

Я хочу выбрать случайную строку с различной вероятностью колонки на основе:Выберите случайную строку с различной вероятностью - SQL

ID  Type 
Bike 1 
Moto 1 
Asus 2 
Car 1 
Apple 2 
John 3 

Если я это сделать я буду иметь случайную вероятность:

выбрать топ 1 * из Пункты заказа по NEWID()

Я хочу, чтобы Джон (тип 3) имеет 70% вероятность получить, и 5% для 1-го типа и 25% для типа 2.

+1

Возможный дубликат [Выбрать случайную строку из таблицы PostgreSQL со взвешенными вероятностями строк] (http://stackoverflow.com/questions/13040246/select-random-row-from-a-postgresql-table-with-weighted- row-probabilities) – Magnus

ответ

4

Я использовал бы функцию RAND() вместо NEWID().

Используя RAND(), мы можем сгенерировать случайное число от 1 до 100, а затем использовать оператор CASE, чтобы выбрать type на основе числа, генерируемого случайным образом.

В соответствии с MSDN:

RAND() возвращает псевдослучайное значение с плавающей точкой в ​​диапазоне от 0 до 1, эксклюзивного

Это означает, что умножение RAND() 100 даст нам число от 0 до 99 . Добавление 1 изменяет диапазон от 1 до 100.

Если после выбора, который возвращает type, вы хотите случайным образом выбрать запись из этого type, вы можете добавить SELECT TOP 1 ... ORDER BY NEWID(), чтобы получить случайную запись этого типа:

DECLARE @Random INT 
SET @Random = (RAND() * 100) + 1 

SELECT TOP 1 ID, Type 
FROM Items 
WHERE Type = CASE 
    WHEN @Random > 30 THEN 3 
    WHEN @Random BETWEEN 6 AND 30 THEN 2 
    ELSE 1 
END 
ORDER BY NEWID() 

See it here ... запустить его несколько раз, чтобы увидеть, что результаты совпадают с вероятностями.

+0

В чем смысл + 1? Похоже, что он отбрасывает проценты, составляя 4% за 1, 25% за 2 и 71% за 3. –

+0

@ Love2Learn Я обновил ответ с объяснением '+ 1'. Без него диапазон будет от 0 до 99 на основе возможных значений возврата для 'RAND()' –

+0

Да, только что заметил, что вы неявно конвертируете в int, прямо на. Я думаю, вам нужно настроить диапазоны, потому что есть только 4 шанса для 1, 25 для 2 и 71 для 3. Измените 3 на 31+ и от 2 до 6 до 30? –

1

Вы имеете в виду вероятность 5% для целой группы типа = 1 или хотите, чтобы каждая запись типа = 1 имела вероятность 5% выбора? Если это второй вариант, тогда у вас есть 70 + 15 + 50 = 135 = вы не можете это сделать. Если это первый вариант, вам придется сделать 2 ничьи - сначала для типа, а затем для строки в этом типе.

Смежные вопросы