Примечание. Я попытался найти другие вопросы и ответы, касающиеся этой проблемы, но не смог найти ни одного, который бы действительно соответствовал моей проблеме и представлял полное решение.
Я пытаюсь сгенерировать случайные синтетические данные для проверки схемы моей базы данных, используя SQL. Генерация множества случайных значений в PostgreSQL с помощью random()
достаточно проста, а генерация случайных наборов данных, сохраняющих ограничения и характеристики данных, которые я ожидаю увидеть, — нет. В частности, у меня есть следующие таблицы:
CREATE TABLE suites(
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name TEXT
);
INSERT INTO suites(name)
SELECT 'suite' || g FROM generate_series(1,50) g;
CREATE TABLE tests(
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name TEXT
);
INSERT INTO tests(name)
SELECT 'test' || g FROM generate_series(1,100) g;
CREATE TABLE tests_in_suites(
suite_id BIGINT,
test_id BIGINT,
PRIMARY KEY (suite_id, test_id)
);
Я хочу заполнить tests_in_suites
случайными значениями, чтобы каждый набор содержал случайное число (от 3 до 7) тестов, равномерно выбранных из tests
. Я хочу, чтобы выбор был случайным и однородным, а также избегал циклов и других повторяющихся шаблонов. Я пробовал следующий подход:
SELECT s.id, t.id FROM
(select id from suites) s,
(SELECT id FROM tests ORDER BY random() LIMIT 2 + ceil(random() * 5)) t
ORDER BY s.id, t.id;
Но он всегда выбирает одинаковое количество тестов для каждого набора, и выбранные тесты идентичны, потому что оптимизатор заменяет подзапрос для s
константой. Я попытался ввести зависимость от текущего рассматриваемого набора, но он жалуется, что значение, которое я пытаюсь использовать, недоступно:
SELECT s.id, t.id FROM
(select id from suites) s,
(SELECT id FROM tests ORDER BY random() LIMIT 2 + ceil(random() * 5 + s.id*0)) t
ORDER BY s.id, t.id;
ERROR: invalid reference to FROM-clause entry for table "s"
LINE 3: ...s ORDER BY random() LIMIT 2 + ceil(random() * 5 + s.id*0)) t
^
HINT: There is an entry for table "s", but it cannot be referenced from this part of the query.
Как я могу генерировать свои случайные данные, не становясь жертвой ни оптимизатора, ни неверных зависимостей данных в моем запросе?