Задание диапазона для столбца SQL - PullRequest
1 голос
/ 22 декабря 2011

У меня есть таблица SQL, в которой у меня есть столбец и вероятность.Я хочу выбрать из него одну строку случайным образом, но я хочу дать больше шансов для более взвешенной вероятности.Я могу сделать это с помощью

    Order By abs(checksum(newid()))

Но разница между вероятностями слишком велика, так что это дает больше шансов для наибольшей вероятности. Как после выбора 74-кратного значения, оно выбирает другое значение один раз, а не снова около 74 раз..Я хочу уменьшить это. Как я хочу, чтобы в 3-4 раза, и чем другие и все.Я думаю, чтобы дать диапазон для вероятностей. Это как

    Row[i] = Row[i-1]+Row[i]

Как я могу это сделать. Мне нужно создать функцию? Есть ли какой-либо другой способ добиться этого. Я новичок. Любойпомощь будет оценена. Спасибо

РЕДАКТИРОВАТЬ: У меня есть решение моей проблемы.У меня есть один вопрос .если у меня есть таблица следующим образом.

    Column1   Column2
     1         50
     2         30
     3         20

Могу ли я получить?

    Column1   Column2  Column3
     1         50       50
     2         30       80
     3         20       100

Каждый раз, когда я хочу добавить значение с существующим. Есть ли способ?

ОБНОВЛЕНИЕ: Наконец, через 3 часа получаем решение, я просто извлекаю квадратный корень из моих вероятностей, чтобы уменьшить разницу между ними. Это похоже на добавление столбца с

    sqrt(sqrt(sqrt(Probability)))....:-)

Ответы [ 4 ]

0 голосов
/ 23 декабря 2011

Вот базовый пример того, как выбрать одну строку из таблицы с учетом назначенных весов строк.

Предположим, у нас есть таблица:

CREATE TABLE TableWithWeights(
  Id int NOT NULL PRIMARY KEY,
  DataColumn nvarchar(50) NOT NULL,
  Weight decimal(18, 6) NOT NULL -- Weight column
) 

Давайте заполним таблицу с образцами данных.

INSERT INTO TableWithWeights VALUES(1, 'Frequent', 50)
INSERT INTO TableWithWeights VALUES(2, 'Common', 30)
INSERT INTO TableWithWeights VALUES(3, 'Rare', 20)

Это запрос, который возвращает одну случайную строку с учетом заданного веса строки.

SELECT * FROM
   (SELECT tww1.*,     -- Select original table data
     -- Add column with the sum of all weights of previous rows
     (SELECT SUM(tww2.Weight)- tww1.Weight  
      FROM TableWithWeights tww2
      WHERE tww2.id <= tww1.id) as SumOfWeightsOfPreviousRows
    FROM TableWithWeights tww1) as tww,
    -- Add column with random number within the range [0, SumOfWeights)
    (SELECT RAND()* sum(weight) as rnd    
     FROM TableWithWeights) r 
WHERE  
         (tww.SumOfWeightsOfPreviousRows <= r.rnd) 
     and ( r.rnd < tww.SumOfWeightsOfPreviousRows + tww.Weight) 

Чтобы проверить результаты запроса, мы можем выполнить его 100 раз.

DECLARE @count as int;
SET @count = 0;
WHILE ( @count < 100)
BEGIN
    -- This is the query that returns one random row with
    -- taking into account given row weights
    SELECT * FROM
       (SELECT tww1.*,     -- Select original table data
         -- Add column with the sum of all weights of previous rows
         (SELECT SUM(tww2.Weight)- tww1.Weight  
          FROM TableWithWeights tww2
          WHERE tww2.id <= tww1.id) as SumOfWeightsOfPreviousRows
        FROM TableWithWeights tww1) as tww,
       -- Add column with random number within the range [0, SumOfWeights)
       (SELECT RAND()* sum(weight) as rnd    
        FROM TableWithWeights) r 
    WHERE  
         (tww.SumOfWeightsOfPreviousRows <= r.rnd) 
     and ( r.rnd < tww.SumOfWeightsOfPreviousRows + tww.Weight) 

    -- Increase counter
    SET @count += 1
END 

PS Запрос был протестирован на SQL Server 2008 R2. И, конечно, запрос может быть оптимизирован (это легко сделать, если вы поймете идею)

0 голосов
/ 22 декабря 2011

Поскольку разница в вероятностях слишком велика, вам нужно добавить вычисляемое поле с пересмотренным взвешиванием, которое имеет более равномерное распределение вероятностей. Как вы это сделаете, зависит от ваших данных и предпочтительного распределения. Один из способов сделать это - «нормализовать» взвешивание до целого числа от 1 до 10, чтобы самая низкая вероятность никогда не была более чем в десять раз меньше самой высокой.

0 голосов
/ 22 декабря 2011

Ответ на ваш недавний вопрос:

SELECT t.Column1, 
       t.Column2,
       (SELECT SUM(Column2) 
        FROM table t2
        WHERE t2.Column1 <= t.Column1) Column3
FROM table t
0 голосов
/ 22 декабря 2011

Я бы справился с чем-то вроде

ORDER BY rand()*pow(<probability-field-name>,<n>)

для разных значений n вы будете искажать линейные вероятности в простой многочлен. Малые значения n (например, 0,5) сжимают вероятности до 1 и, таким образом, делают менее вероятный выбор более вероятным, большие значения n (например, 2) сделают обратное и еще больше уменьшат вероятность уже непробиваемых значений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...