powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / select... random - как сделать?
19 сообщений из 19, страница 1 из 1
select... random - как сделать?
    #36456974
Фотография Di_LIne
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
(Yaffil)
1. Есть: табля в которой 150 тыщ строк.
2. Нужно: Сделать выборку RANDOM 150 строк.
3. Как это сделать не на клиенте?
...
Рейтинг: 0 / 0
select... random - как сделать?
    #36457202
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
select first  150  *
  from table1
  order by rand()
...
Рейтинг: 0 / 0
select... random - как сделать?
    #36457507
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выше было предложено следующее:
Гаджимурадов Рустам
Смотря какая рандомность нужна...
Самое тупое
Код: plaintext
1.
2.
3.
Select First  150  *
From Table
Where (PK div  150  =  0 ) -- как делается div, думаю, знаешь
Для пущей красоты можно точку старта менять - чтобы
первая строчка каждый раз в выборку не попадала -
с помощью SKIP или с помощью (Where PK > :start)

Способ чуть умнее
Код: plaintext
1.
2.
3.
Select First  150  *
From Table
Where (PK = random( 150000 ))

Код: plaintext
Where (PK =  150000 *rand())

Я посчитал что выдать результат, который просит Диля оно не сможет и удалил как "вредные советы".

Если Рустам покажет , что таки может, готов извиниться.
...
Рейтинг: 0 / 0
select... random - как сделать?
    #36457768
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Di_LIne(Yaffil)
1. Есть: табля в которой 150 тыщ строк.
2. Нужно: Сделать выборку RANDOM 150 строк.
3. Как это сделать не на клиенте?а поле PK - с дырками или без ?
...
Рейтинг: 0 / 0
select... random - как сделать?
    #36457861
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Рустам, действительно, не ругал моё предложение, а наоборот, сказал "о да!".
Вот только не из той же оперы, не из той же.

Я без тынца тут свои мысли навалю кучкой.
Проверка условия PK = random(150000) имхо не сработает никогда, потому что вероятность, что совпадёт значение PK и значение рандома ничтожно мала.
...
Рейтинг: 0 / 0
select... random - как сделать?
    #36457893
Фотография Di_LIne
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоида поле PK - с дырками или без ?
А как жеж без них-то?
...
Рейтинг: 0 / 0
select... random - как сделать?
    #36458240
Senya_L
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Di_LIne,

Варианты с ХП принимаются?
...
Рейтинг: 0 / 0
select... random - как сделать?
    #36458393
Senya_L
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Senya_LDi_LIne,

Варианты с ХП принимаются?Не, отставить ХП. Тормозно получается. SKIP не умеет читать по индексу. :(
...
Рейтинг: 0 / 0
select... random - как сделать?
    #36458542
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На почти миллионе мелких записей

select first 150 * from table1 order by rand() 13000msec

Select First 150 * From Table Where mod(PK,150)=0 10ms - конечно случайности мало

Where (PK = 150000*rand()) 2.3 sec, результата нет


Select First 150 * From Table Where mod(PK,rand()*10000+1)=0 31ms - случайность есть, но относительный порядок записей сохраняется

а теперь финалист
select * from (Select First 150 * From Table Where mod(PK,rand()*10000+1)=0) order by rand(); тоже 31ms



PK у меня не было, я его эмулировал
extract(second from msgdate) * extract(yearday from msgdate)

FB 2.5RC2
...
Рейтинг: 0 / 0
select... random - как сделать?
    #36458572
Senya_L
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SiemarglSelect First 150 * From Table Where mod(PK,rand()*10000+1)=0 31ms - случайность есть, но относительный порядок записей сохраняется

а теперь финалист
select * from (Select First 150 * From Table Where mod(PK,rand()*10000+1)=0) order by rand(); тоже 31msСтрого говоря оба этих супер-быстрых методов не дают гарантии, что получишь заказанное количество строк. ;)
...
Рейтинг: 0 / 0
select... random - как сделать?
    #36458617
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Senya_L,

Конечно, надо соотносить величину делителя и кол-ва записей в таблице.
...
Рейтинг: 0 / 0
select... random - как сделать?
    #36458754
Senya_L
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SiemarglSenya_L,

Конечно, надо соотносить величину делителя и кол-ва записей в таблице.И даже если соотнесешь - гарантии нет. Особенно на небольших таблицах.

Кроме того, есть подозрение, что мат. ожидание для всех записей вряд ли будет одинаковым. Проще говоря, для первых записей вероятность попасть в выборку будет больше.
...
Рейтинг: 0 / 0
select... random - как сделать?
    #36458936
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как вариант, попробовал портировать решение, которое используется на mysql.
Генерируем нужное кол-во случайных чисел из отрезка min(ID) .. max(ID) и получаем что-то типа:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
select first  1  * from contact where id >=  3346296 
union all
select first  1  * from contact where id >=  2701698 
union all
select first  1  * from contact where id >=  395237 
union all
select first  1  * from contact where id >=  3229246 
union all
select first  1  * from contact where id >=  1178944 
150 юнионов это конечно жесть, но можно, например, завернуть в union 15 запросов с first 10, если задача позволяет.

Заметил небольшие тормоза, если под условие id > xxx попадает много записей, как я понял, first не оптимизируется. Если интервал ограничить сверху, получается неплохо.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
select first  10  * from contact where id between  2754175  and  2754175 + 100 
union all
select first  10  * from contact where id between  1006450  and  1006450 + 100 
union all
select first  10  * from contact where id between  1855813  and  1855813 + 100 
union all
select first  10  * from contact where id between  853231  and  853231 + 100 
union all
select first  10  * from contact where id between  3077590  and  3077590 + 100 
в таблице contact 3 млн записей, результат:
Prepare time = 0ms
Execute time = 16ms

P.S.
из-за дырок может получится меньше записей, + могут появится повторы. Как вариант, можно сразу запрашивать больше записей или повторить процедуру еще раз.
...
Рейтинг: 0 / 0
select... random - как сделать?
    #36459022
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня есть таблица с крайне дырявым ПК, в ней примерно 400 тыс строк.
Решил добавить к ней индекс по убыванию поля ID (чтобы быстрее определялся MAX(ID)).
Затем сделал ХП, в которой генерится числовой ряд от 1 до 100 тыс со случайными значениями:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
create procedure ZZZ_GET_RAND (
    A_LIM integer)
returns (
    ROW_NUM integer,
    RND_VAL integer)
as
declare variable V_MAX_ID integer;
declare variable V_RND integer;
begin
select max(id) from zzz_test_tab into :v_max_id;
for
  with
  nx as(
    select  0  i from rdb$database union all
    select  1  from rdb$database union all
    select  2  from rdb$database union all
    select  3  from rdb$database union all
    select  4  from rdb$database union all
    select  5  from rdb$database union all
    select  6  from rdb$database union all
    select  7  from rdb$database union all
    select  8  from rdb$database union all
    select  9  from rdb$database
  )
  ,n as(
    select t.i+ 1  i, cast(rand()*:v_max_id as int) r
    from(select n4.i* 10000 + n3.i* 1000 +n2.i* 100 +n1.i* 10 +n0.i i from nx n4, nx n3, nx n2,nx n1,nx n0
    ) t
    where t.i<=:a_lim
  )
select n.i, n.r
  from n
into
  :row_num,
  :rnd_val
do
  suspend;
end
И дальше сделал так:
Код: plaintext
1.
2.
select first  150   t.id
from ZZZ_GET_RAND( 100000 ) zzz
join zzz_test_tab t on zzz.rnd_val=t.id
В это трудно поверить, но отработало достаточно быстро:
Код: plaintext
1.
2.
3.
------ Performance info ------
Prepare time = 0ms
Execute time = 1s 297ms
Avg fetch time = 43,23 ms

Хотя, конечно же, никакой гарантии на то, что 100 тыс строк дадут при соединении не менее 150, нету.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
select... random - как сделать?
    #39044683
tosick4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А как сделать что бы вероятность была одинакова для всех чисел диапазона?
Мне нужно целое в диапазоне 10-13 . Делаю так:
SELECT (ROUND(10+(RAND(CHECKSUM(NEWID()))*3),0))
Но все равно числа 10 и 13 выпадают реже чем 11 и 12 .
...
Рейтинг: 0 / 0
select... random - как сделать?
    #39044715
miwaonline
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tosick4,

Что значит "реже"? Сколько опытов было проведено прежде чем придти к такому выводу?
...
Рейтинг: 0 / 0
select... random - как сделать?
    #39044731
tosick4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Около 50 тыс. Мне подсказали - использовать вместо round функцию cast!
...
Рейтинг: 0 / 0
select... random - как сделать?
    #39044915
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tosick4числа 10 и 13 выпадают реже чем 11 и 12 .
Код: plaintext
select ( 10-0.5 ) +  rand() * (  13+0.5  - ( 10-0.5 ) ) from rdb$database
...
Рейтинг: 0 / 0
select... random - как сделать?
    #39044940
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tosick4,

Таблоид уже дал тебе ответ, но я поясню его: если для любого числа внутри диапазона, например, 11, попадают значения от 10.5 до 11.5 (не включая), то для "граничного числа" 10 попадают только от 10 до 10.5 (не включая), т.е. в 2 раза меньше.
Потому нужно раздвинуть по 0.5 границы генерируемых значений.
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / select... random - как сделать?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]