Я пишу некоторый SQL в хранимой процедуре, чтобы уменьшить набор данных до ограниченного случайного числа строк, о котором я хочу сообщить.Использование NEWID() с помощью CTE для создания произвольного подмножества строк дает нечетные результаты
Отчет начинается с Group
из Users
и применяется фильтр для указания общего количества необходимых случайных строк (@SampleLimit
).
Для того, чтобы достичь желаемого результата, я начать с создания КТР (временную таблицу) с:
top(@SampleLimit)
применяетсяgroup by UserId
(как Идентификатор_пользователя появляется несколько раз)order by NEWID()
ставить результаты в случайном порядке
SQL:
; with cte_temp as
(select top(@SampleLimit) UserId from QueryResults
where (GroupId = @GroupId)
group by UserId order by NEWID())
Как только у меня есть этот результирующий набор, я удаляю любые результаты, когда UserId равен NOT IN
CTE, созданному на предыдущем шаге.
delete QueryResults
where (GroupId = @GroupId) and (UserId not in(select UserId from cte_temp))
Вопрос, который я имею, что время от времени, я получаю больше результатов, чем указано в @SampleLimit
и другие времена он работает именно так, как ожидалось.
Я пробовал разбить SQL и выполнить его вне приложения, и я не могу воспроизвести проблему.
Есть ли что-то принципиально неправильное в отношении того, что я делаю, что может объяснить, почему я иногда получаю больше результатов, которые я запрашиваю?
Для полноты - мое повторно учитываться решение, основанное на ниже ответа:
select top(@SampleLimit) UserId into #T1
from QueryResults
where (GroupId = @GroupId)
group by UserId
order by NEWID()
delete QueryResults
where (GroupId = @GroupId) and (UserId not in(select UserId from #T1))
Я хотел бы предложить, что 'SELECT DISTINCT TOP (@SampleLimit) ...' будет работать быстрее, чем 'GROUP BY'. – Stoleg
Получите больше результатов, оставшихся после того, как вы «УДАЛИТЬ ... ГДЕ UserID not IN (...)»? – Stoleg
@Stoleg да, удалять оставляют больше пользователей, чем я указал.Я проверю план выполнения для вашего предложения выше – Tanner