Как случайным образом выбрать строки в SQL?
Я использую MSSQL Server 2005. В моей БД у меня есть таблица "customerNames", которая имеет два столбца "Id" и "Name" и прибл. 1000 результатов.
Я создаю функциональность, где я должен выбрать 5 клиентов случайным образом каждый раз. Может ли кто-нибудь сказать мне, как создать запрос, который будет получать случайные 5 строк (Id и Name) каждый раз при выполнении запроса?
9 ответов
SELECT TOP 5 Id, Name FROM customerNames
ORDER BY NEWID()
тем не менее, все, кажется, приходят на эту страницу для более общего ответа на ваш вопрос:
выбор случайной строки в SQL
выберите случайную строку с MySQL:
SELECT column FROM table
ORDER BY RAND()
LIMIT 1
выберите случайную строку с PostgreSQL:
SELECT column FROM table
ORDER BY RANDOM()
LIMIT 1
выберите случайную строку с Microsoft SQL Server:
SELECT TOP 1 column FROM table
ORDER BY NEWID()
выберите случайную строку с IBM DB2
SELECT column, RAND() as IDX
FROM table
ORDER BY IDX FETCH FIRST 1 ROWS ONLY
выбрать случайную запись с Оракул:
SELECT column FROM
( SELECT column FROM table
ORDER BY dbms_random.value )
WHERE rownum = 1
выберите случайную строку с sqlite:
SELECT column FROM table
ORDER BY RANDOM() LIMIT 1
может быть этот сайт будет помощи.
для тех, кто не хочет нажимать:
SELECT TOP 1 column FROM table
ORDER BY NEWID()
здесь есть хорошее решение Microsoft SQL Server 2005. Имеет дело с проблемой, когда вы работаете с большим набором результатов (не вопрос, который я знаю).
выбор строк случайным образом из большой таблицы http://msdn.microsoft.com/en-us/library/cc441928.aspx
Я нашел, что это лучше всего работает для больших данных.
`SELECT TOP 1 Column_Name FROM dbo.Table TABLESAMPLE(1 PERCENT);`
TABLESAMPLE(n ROWS) or TABLESAMPLE(n PERCENT)
является случайным, но нужно добавить TOP n
чтобы получить правильный размер образца.
используя NEWID()
очень медленно на больших таблицах.
Если у вас есть таблица с миллионами строк и заботятся о производительности, это может быть лучший ответ:
SELECT * FROM Table1
WHERE (ABS(CAST(
(BINARY_CHECKSUM
(keycol1, NEWID())) as int))
% 100) < 10
Это старый вопрос, но попытка применить новое поле (NEWID() или ORDER BY rand()) к таблице с большим количеством строк будет непомерно дорогой. Если у вас есть инкрементные, уникальные идентификаторы (и не имеют отверстий), будет более эффективно вычислить X # идентификаторов, которые будут выбраны вместо применения GUID или аналогичного каждой отдельной строке, а затем принимая верхний X#.
DECLARE @maxValue int = (select max(id) from [TABLE])
DECLARE @minValue int = (select min(id) from [TABLE])
DECLARE @randomId1 int, @randomId2 int, @randomId3 int, @randomId4 int, @randomId5 int
SET @randomId1 = ((@maxValue + 1) - @minValue) * Rand() + @minValue
SET @randomId2 = ((@maxValue + 1) - @minValue) * Rand() + @minValue
SET @randomId3 = ((@maxValue + 1) - @minValue) * Rand() + @minValue
SET @randomId4 = ((@maxValue + 1) - @minValue) * Rand() + @minValue
SET @randomId5 = ((@maxValue + 1) - @minValue) * Rand() + @minValue
--select @maxValue as MaxValue, @minValue as MinValue
-- , @randomId1 as SelectedId1
-- , @randomId2 as SelectedId2
-- , @randomId3 as SelectedId3
-- , @randomId4 as SelectedId4
-- , @randomId5 as SelectedId5
select *from[TABLE] el
where el.id in (@randomId1, @randomId2, @randomId3, @randomId4, @randomId5)
Если вы хотите выбрать еще много строк, я бы посмотрел на заполнение #tempTable с идентификатором и кучей значений rand (), затем используя каждое значение rand () для масштабирования до значений min-max. Таким образом, вам не нужно определять все @randomId1...параметры N. Я включил пример ниже, используя cte для заполнения начальной таблицы.
DECLARE @NumItems int = 100;
DECLARE @maxValue int = (select max(id) from [TABLE])
DECLARE @minValue int = (select min(id) from [TABLE])
with cte (n) as (select 1 union all select n+1 from cte where n < @NumItems)
select cast( ((@maxValue + 1) - @minValue) * rand(cast(newid() as varbinary(100))) + @minValue as int) as tp into #Nt
from
cte
select * from #Nt ntt
inner join [TABLE] i
on i.id = ntt.tp
drop table #Nt