2012-03-16 1 views
1

Мне нужно извлечь две случайные записи из таблицы. Я реализовал что-то вроде этого внутри хранимой процедуры:tsql случайные записи извлечение возвращает дубликаты

with tmpTable as(
     SELECT top 500 [columns I need] 
       , row_number() over(order by [myColumn]) as rown 
     FROM SourceTable 
      JOIN [myJoin] 
     WHERE [myCondition] 
    ) 
    -- here I extract with an intervall of 10 records: 10, 20, 30, ..., 400, 410, ... 
    select * from tmpTable where rown = (1 + FLOOR(50*RAND()))*10 

Он отлично работает, он извлекает случайную запись из первых 500 записей из моего источника. Но, когда sp вызывается из уровня представления (ASP.NET 4.0, SqlClient ADO.NET), в конечном итоге одна и та же запись возвращается дважды. Обратите внимание, что оба вызова являются независимыми друг от друга.

Я думаю, это зависит от того, что sp вызывается дважды за несколько миллисекунд и что случайный генератор создает одинаковое число. В процессе отладки не происходит дублирования: из-за шагов вручную F10, я думаю, для этого требуется более нескольких миллисекунд.

Как я могу получить две разные записи?

EDIT

Ответ Lamak требует еще некоторые детали. Исходная таблица состоит из записей продуктов. Группы из примерно 10 записей отличаются друг от друга только для некоторых carachteristics (например, цвета). Записи распределяются таким образом:

1 to 10: product 1 
11 to 20: product 2 
... and so on 

Так что, если я получаю первые две случайные записи настоятельно ожидается, что записи будут рассматривать один и тот же продукт. Вот почему я использую intervall из 10 записей в случайном извлечении.

ответ

1

Если вы используете SQL Server, вы можете просто сделать следующее:

SELECT TOP 1 [columns I need] 
FROM SourceTable 
JOIN [myJoin] 
ON [Something] 
WHERE [MyCondition] 
ORDER BY NEWID() 

Если вы все еще хотите первым изолировать записи для каждого продукта, вы можете попробовать это:

SELECT TOP 1 * 
FROM ( SELECT [columns I need], ROW_NUMBER() OVER(PARTITION BY Product ORDER BY NEWID()) Corr 
     FROM SourceTable 
     JOIN [myJoin] 
     ON [Something] 
     WHERE [MyCondition]) A 
WHERE Corr = 1 
ORDER BY NEWID() 

Хотя вы все равно можете выбрать запись, которая имеет тот же продукт первого.

+0

Спасибо за ответ. Я только что добавил некоторые подробности. –

+0

И почему вы думаете, что при выборе 2 случайных значений (даже если они находятся в группах продуктов), ожидается, что записи будут рассматривать один и тот же продукт ?, они выбраны случайными, так что это не так. – Lamak

+0

Я вижу ваш но, как я добавил, эти два вызова являются независимыми. –

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

  • Нет связанных вопросов^_^