TomHunn Ответов: 2

Как вы генерируете таблицу со случайными значениями, взятыми из других таблиц в postgresql?


Следующий код генерирует 100000 строк со случайными значениями для столбца Id с помощью функции uuid_generate_v4(). Однако вложенные выборки всегда выбирают одну и ту же строку, поэтому все вставленные строки имеют одинаковые значения для этих столбцов. Цель состоит в том, чтобы создать таблицу из 100 тысяч строк со случайными значениями, взятыми из других выборочных таблиц. Каждая из выборочных таблиц имеет только два столбца (Id и столбец, из которого берутся значения). Как это можно заархивировать?

Что я уже пробовал:

insert into "Tag" (

"Id", "Time", "Account", "Name", "Value", "RollUpTableId"

)

select

uuid_generate_v4(),

current_timestamp,

(select "Account" from "AccountSamples" OFFSET floor(random()*358) LIMIT 1),

(select "Name" from "TagNameSamples" OFFSET floor(random()*19) LIMIT 1),

(select "Value" from "TagValueSamples" OFFSET floor(random()*26) LIMIT 1),

uuid_generate_v4()

from generate_series(1, 100000);


Я также попробовал следующее, что было предложено мне, но дает мне нули(https://codeshare.io/5QD7dq) во многих строках (у меня нет нулей в примерах таблиц, и они имеют только 358, 19 и 26 строк в каждом таком порядке.

insert into "Tag" (

"Id", "Time", "Account", "Name", "Value", "RollUpTableId"
)

select uuid_generate_v4(), current_timestamp, a."Account", tns."Name", tvs."Value", uuid_generate_v4()

from generate_series(1, 1000) x(rn)

left join (

select "Account", row_number() over(order by random()) rn from "AccountSamples"

) a on a.rn = x.rn

left join (

select "Name", row_number() over(order by random()) rn from "TagNameSamples"

) tns on tns.rn = x.rn

left join (

select "Value", row_number() over(order by random()) rn from "TagValueSamples"

) tvs on tvs.rn = x.rn


Я тоже пытался
select "Account" from "AccountSamples" where "Id" = (trunc(random() * 358)::integer)

2 Ответов

Рейтинг:
9

TomHunn

Цитата:
В вашем первом решении проблема заключается в том, что подвыборка не имеет никакой внешней зависимости, поэтому она будет оптимизирована для вызова random только один раз. Вы можете исправить это, добавив внешнюю зависимость. Попробуйте что-нибудь вроде этого:

select uuid_generate_v4(),
       current_timestamp,
       (select "Account" from "AccountSamples" WHERE gen=gen OFFSET floor(random()*358) LIMIT 1),
       (select "Name" from "TagNameSamples" WHERE gen=gen OFFSET floor(random()*19) LIMIT 1),
       (select "Value" from "TagValueSamples" WHERE gen=gen OFFSET floor(random()*26) LIMIT 1 ),
       uuid_generate_v4()
  from generate_series(1, 100000) gen;


Кстати, типичный способ выбрать случайным образом из таблицы без необходимости предварительного расчета размера таблицы-это что-то вроде

SELECT foo FROM bar ORDER BY random() LIMIT 1


Он не слишком эффективен, но прост и хорошо понятен.


от Reddit.


Рейтинг:
2

TomHunn

Спасибо, решение, предоставленное pehrs, сработало. Однако я принимаю к сведению вашу ссылку для дальнейшего использования в этом вопросе.