Сгенерировать случайное число в диапазоне 1-10

99

Поскольку мой подход для тестового запроса, над которым я работал над этим вопросом , не сработал, я сейчас пробую что-то другое. Есть ли способ указать random()функции pg получать мне только числа от 1 до 10?

KB22
источник

Ответы:

159

Если под числами от 1 до 10 вы имеете в виду любое число с плавающей запятой от> = 1 до <10, то это просто:

select random() * 9 + 1

Это можно легко проверить с помощью:

# select min(i), max(i) from (
    select random() * 9 + 1 as i from generate_series(1,1000000)
) q;
       min       |       max
-----------------+------------------
 1.0000083274208 | 9.99999571684748
(1 row)

Если вам нужны целые числа> = 1 и <10, то это просто:

select trunc(random() * 9 + 1)

И снова простой тест:

# select min(i), max(i) from (
    select trunc(random() * 9 + 1) as i from generate_series(1,1000000)
) q;
 min | max
-----+-----
   1 |   9
(1 row)
Клесун
источник
выберите дату (e.created_at) + (trunc (random () * 20)) из событий e; результат: ОШИБКА: оператор не существует: дата + двойная точность. Действительно ли trunc возвращает целые числа?
Богдан Гусиев
3
trunc()возвращает тот же тип данных, что и входные (как указано в руководстве). Вам нужно преобразовать результат в целое число:trunc(random() * 20)::int
a_horse_with_no_name 05
Интересно, возможно ли, по крайней мере теоретически, random()вернуть значение <1, которое при умножении на 9 будет> = 9 из-за неточной природы типа двойной точности ? На практике, даже если это возможно, это, конечно, было бы маловероятным из-за точности в 15 или около того.
1
Я играю с width_bucket(random(), 0, 1, 10)альтернативой
Похоже, мои опасения были беспочвенными, хотя, признаюсь, я вообще не разбираюсь в математике :-)
18

Подводя итог и немного упрощая, вы можете использовать:

-- 0 - 9
select floor(random() * 10);
-- 0 - 10
SELECT floor(random() * (10 + 1));
-- 1 - 10
SELECT ceil(random() * 10);

И вы можете проверить это, как указано в @ user80168

-- 0 - 9
SELECT min(i), max(i) FROM (SELECT floor(random() * 10) AS i FROM generate_series(0, 100000)) q;
-- 0 - 10
SELECT min(i), max(i) FROM (SELECT floor(random() * (10 + 1)) AS i FROM generate_series(0, 100000)) q;
-- 1 - 10
SELECT min(i), max(i) FROM (SELECT ceil(random() * 10) AS i FROM generate_series(0, 100000)) q;
qd3v
источник
2
В документах говорят , «случайное значение в диапазоне 0,0 <= х <1.0», так что , по крайней мере теоретическая вероятность в ceil(random() * 10)результате 0 - я бы придерживаться floor.
1
Я согласен с @JackDouglas, поэтому для диапазона 1-10 это должно бытьSELECT floor(random() * 10 + 1);
Сергей Колесников
9

Если вы используете SQL Server, то правильный способ получить целое число:

SELECT Cast(RAND()*(b-a)+a as int);

куда

  • 'b' - верхний предел
  • 'a' - нижний предел
Неха Джайн
источник
Будьте осторожны, если вы установите нижний предел равным 1, а верхний - 10, вы получите только числа 1-> 9. Другие ответы, похоже, предполагают, что между 1 и 10 означает 1-> 9 ... Я бы предложил, если «между» исключает верхнюю границу, он также должен исключать нижнюю (т.е. 2-> 9). ВЫБРАТЬ Cast (RAND () * ((b + 1) -a) + a как int);
Морваэль
Вопрос явно помечен как вопрос PostgreSQL.
Себастьян Пальма
4

(усечение (случайное () * 10)% 10) + 1

Hythlodayr
источник
ОШИБКА: оператор не существует: двойная точность% целое число
1
И зачем вам вообще использовать модуль? В этой логике нет смысла. Если у вас будет какая-то «упаковка», у вас не будет равного распределения, а если вы ее не получите, то она вам не понадобится.
ErikE
1

Правильная версия ответа hythlodayr.

-- ERROR:  operator does not exist: double precision % integer
-- LINE 1: select (trunc(random() * 10) % 10) + 1

Вывод из truncдолжен быть преобразован в INTEGER. Но это можно сделать безtrunc . Оказывается, все просто.

select (random() * 9)::INTEGER + 1

Создает вывод INTEGER в диапазоне [1, 10], то есть от 1 до 10 включительно.

Для любого числа (с плавающей точкой) см. Ответ user80168. т.е. просто не конвертируйте его в INTEGER.

мифический кодер
источник
0

На самом деле я не знаю, что вы этого хотите.

попробуй это

INSERT INTO my_table (my_column)
SELECT
    (random() * 10) + 1
;
Leejaycoke
источник
0

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

создать таблицу для курсора:

CREATE TABLE [dbo].[SearchIndex](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Cursor] [nvarchar](255) NULL) 

ИДТИ

Создайте таблицу со своими числами:

CREATE TABLE [dbo].[ID](
[IDN] [int] IDENTITY(1,1) NOT NULL,
[ID] [int] NULL)

ВСТАВКА СКРИПТА:

INSERT INTO [SearchIndex]([Cursor])  SELECT N'INSERT INTO ID  SELECT   FLOOR(rand() * 9 + 1)  SELECT COUNT (ID) FROM ID

СОЗДАНИЕ И ВЫПОЛНЕНИЕ ПРОЦЕДУРЫ:

CREATE PROCEDURE [dbo].[RandNumbers] AS
BEGIN
Declare  CURSE  CURSOR  FOR (SELECT  [Cursor] FROM [dbo].[SearchIndex]  WHERE [Cursor] IS NOT NULL)
DECLARE @RandNoSscript NVARCHAR (250)
OPEN CURSE
FETCH NEXT FROM CURSE
INTO @RandNoSscript 
WHILE @@FETCH_STATUS IS NOT NULL 
BEGIN
Print @RandNoSscript
EXEC SP_EXECUTESQL @RandNoSscript;  
 END
 END
GO

Заполните свою таблицу:

EXEC RandNumbers
Абу Халил Мохамед
источник
3
Вопрос в Postgres, а не в SQL Server
a_horse_with_no_name