Контекст
У меня есть таблица PostgreSQL, которая содержит несколько сотен тысяч строк и много столбцов.
Short : я хотел бы инициализировать случайные значения в некоторых столбцах в соответствии с равномерным распределением или нормальным распределением .
Равномерное распределение
У меня есть 3 пустых столбца, которые я хотел бы инициализировать с помощью одинаковых случайных чисел (т.е. согласно равномерное распределение по каждому столбцу).
Для этого я использую функцию PostgreSQL random()
, но в документации неясно, выбраны ли сгенерированные числа из равномерного или нормального распределения:
Источник: https://www.postgresql.org/docs/12/functions-math.html
Итак, я высказал (надеюсь правильную) гипотезу, что с сегодняшнего дня это равномерное распределение.
Нормальное распределение
И у меня есть 3 других пустых столбца, которые я хотел бы инициализировать с помощью нормальных случайных чисел (т.е. согласно нормальное распределение по каждому столбцу):
Результаты
Для равномерное распределение
Я сделал это (на самом деле я понял это во время написания этого поста);
UPDATE schema.tables
SET col1 = (1 * random() + 1)::float4,
col2 = (1 * random() + 1)::float4,
col3 = (1 * random() + 1)::float4
Это немного медленно, но, похоже, работает, потому что вот пример сгенерированных данных :
И гистограмма данных для одного столбца почти одинакова, поэтому я думаю, что все в порядке:
Но было бы замечательно установить целые значения столбцов в одном кадре, а не построчно (или, возможно, этот построчный способ обновления таблица действительно лучше работает в SQL. Я не знаю, но это скорее рассуждения по линейной алгебре, которые у меня на заднем плане).
Для нормального распределения
Я застрял в следующем запросе, вдохновленном предыдущим, но использующим функцию normal_rand
из tablefun c расширение:
UPDATE schema.table
SET col1 = (1 * normal_rand(1,50.0,20.0) + 2)::float4),
col2 = (1 * normal_rand(1,50.0,20.0) + 2)::float4),
col3 = (1 * normal_rand(1,50.0,20.0) + 2)::float4),
но здесь я сталкиваюсь со следующей ошибкой: set-returning functions are not allowed in UPDATE
.
Итак, я предположил, что должен использовать SELECT
Подзапрос, следовательно, я тоже попробовал это, но без особого успеха:
UPDATE schema.table
SET col1 = sub.col
FROM (SELECT (1 * normal_rand(1, 50.0, 20.0) + 2)::float4 as col) AS sub,
col2 = sub.col
FROM (SELECT (1 * normal_rand(1, 50.0, 10.0) + 2)::float4 as col) AS sub,
col3 = sub.col
FROM (SELECT (1 * normal_rand(1, 50.0, 5.0) + 2)::float4 as col) AS sub
Где я получаю syntax error at or near col2
Но если я играю с одним столбцом:
UPDATE schema.table
SET col1 = sub.col
FROM (SELECT (1 * normal_rand(1, 50.0, 20.0) + 2)::float4 as col) AS sub;
Он почти работает, запрос выполнен успешно, но у меня есть одинаковое число в каждой строке столбца, что явно не делает его нормальным распределением!
Так что моя мечта можно было бы обновить все столбцы целый за один раз, используя что-то вроде:
UPDATE schema.table
SET col1 = sub.col
FROM (
SELECT (
1 * normal_rand(
SELECT count(*) FROM schema.table,
50.0,
20.0
) + 2
):: float4 AS col
) AS sub;
Но здесь я снова получил синтаксическую ошибку во 2-й позиции SELECT; syntax error at or near "select"
Вопрос
Как мне установить один или несколько целых столбцов со случайными числами в соответствии с нормальным распределением?