Если ваша система использует БД и время от времени нужны тестовые записи, или если вы делаете insert-ы с несколькими наборами значений values, то изложенное ниже может пригодиться. Если у вас есть БД и вы разрабатываете алгоритмы, которые отбирают записи по определённым критериям из одной или нескольких таблиц, значит, на этапе разработки вам нужны тестовые данные, удовлетворяющие заданным условиям. Как же их получить? Первая мысль - найти среди уже имеющихся. Но, чем больше условий, тем больше проблем при поиске.  Допустим, нашли. Разработчику и тестировщику нужно много вариантов набора данных. Можно взять несколько записей и их update-ить, но не помешает ли это кому-то ещё? Не грохнется ли часть данных по какой-нибудь причине? А что будет с этими записями через несколько месяцев, когда понадобится что-то перепроверить? На практике не раз сталкивался с худшими ответами на подобные вопросы. Как же этого избежать?   Если мы знаем в какой таблице какие записи нужны, то самое логичное - делать insert-ы с нужными значениями, с оглядкой на все связи. Да, выглядит сложно и ресурсоёмко, но это только на первый взгляд.  Раз уж мы начинаем разбираться в записях определённой таблицы, то всё равно придётся выяснить: какие в ней поля обязательные, какие связаны с другими таблицами, какие могут принимать значения и т.д. Всё это поможет написать скрипт, который вряд ли завалится из-за изменений в БД. К тому же, разбираться и писать скрипт будет один человек один раз, а использовать его можно будет многократно и кому угодно. Переменные, циклы, условные выражения и подзапросы позволят создать гибкий, легко читаемый и короткий скрипт, генерирующий готовый набор данных. Главная идея - запуском скрипта получать полный набор тестовых данных для одного или нескольких кейсов. Покажу на Transact-SQL для MS SQL Server (на PostgreSQL будет аналогично). Допустим, есть таблица Trades. Нас интересуют данные за вчерашний день. Создадим несколько: Что происходит: Объявляем переменные:  i - для цикла n - нужное количество записей TradeDate - вчерашний день, получаемый вычитанием одного дня из текущей даты-времени Market_id - поле, связанное с какой-то другой таблицей MarketDic. Берём значение id нужного нам Code Currency_id - тоже связанное поле. Но, тут нас устроит любое значение, существующее в некой таблице CurrencyDic. Задаём значение i Пока выполняется условие, делаем insert-ы в нашу таблицуПоля:  id - вычисляем текущее максимальное значение id и увеличиваем его на 1 TradeDate - используем значение одноимённой переменной, т.е вчера AccountName - объединяем в одну строку статичное "Имя_" со значением i. В результате, для соответствующих строк получим Имя_1, Имя_2, ... Имя_5 DealType - для всех чётных строк (чей номер делится на 2 без остатка), значение будет "Buy", а для остальных - "Sell" Market_id и Currency_id - значения одноимённых переменных, описанных выше. Итак, выполнив скрипт, мы за секунду получим готовый набор данных. Чем хорош скрипт: Значение даты всегда нужное, не придётся update-ить Всегда актуальные значения из связанных таблиц Количество генерируемых записей легко меняется Компактный видInsert хотя бы 5 записей через набор значений values (...), (...), ... (...) получился бы гораздо длинней, большинство значений бы повторялось и читалось бы это всё тяжело. Достаточно простая реализацияЕсли уж Вы сюда добрались, скорее всего, про переменные и циклы представление у Вас имеется.Про getdate(), dateadd, concat, case... легко найти информацию в официальной документации и не только. Разумеется, на практике нужно несколько записей в нескольких таблицах, да и полей куда больше. Но, если разберётесь в моём примере, то ни количество таблиц, ни соотношение записей испугать Вас не должны. Чтобы не засорять базу, хорошо бы каждым скриптом удалять записи, полученные от его предыдущего запуска. Для этого, между объявлением переменных и insert-ами, вставляем набор delete-ов.Соответственно, должна быть возможность отделять свои записи от любых других.Я применял 2 способа: Текстовые меткиВ какой-нибудь из таблиц должно быть текстовое поле, куда можно прописать что-то говорящее, вроде "Test_for_Task-12345_1".Такие записи находятся через like 'Test_for_Task-12345_%' или просто равенством.Связанные с ней записи находятся вложенными select-ами и удаляются сначала они, а потом и главная.Может работать медленно, если данных много. Всё-таки like. Заданный диапазон id-шниковВ качестве переменной задаём значение, далёкое от текущего, и от него отталкиваемся: в цикле к переменной прибавляем i.Зная сколько добавляем записей, потом ищем по id через between. Если тест кейсы автоматизируются, то удаление надо прописать так, чтобы оно выполнялось после завершения проверки (положительной или с падением). Почти наверняка нужно будет на одну запись в одной таблице сгенерить несколько в другой. Тут поможет вложенный цикл. Если используете свои id, то алгоритм вычисления id для него будет следующий:  @id + @k + @n2 * (@i - 1) где:  id - вычисленное/желаемое изначальное значение k - переменная внутри вложенного цикла n2 - количество записей вложенного цикла (т.е, while вложенного цикла у нас с условием: k <= n2) i - переменная основного цикла Может очень пригодиться конструкция: if not exists (select ... )Т.е. если по какому-то запросу ничего не находится, то что-то выполняем. При использовании переменных для заполнения полей, как в примере TradeDate, Market_id и Currency_id, их типы должны быть ровно те же, что у самих полей. Чтобы не получилось, что поле типа bigint, а переменная int. Оставляйте минимум вычислений/подзапросов внутри циклов, чтобы они не создавали нагрузку при каждой итерации. В примере, id вычисляется каждый раз, т.к. иначе его не узнать, а Market_id и Currency_id - только при объявлении. В процессе написания скрипта, будете составлять select-ы, показывающие все сгенерированные записи. Сохраните их в конце, в закомментированном виде. Когда в следующий раз Вам, или кому-то из коллег, понадобится разобраться в скрипте, эти запросы сэкономят время. Что изменилось в работе нашей команды после того, как я опробовал на практике и рассказал коллегам об этом подходе к подготовке данных: Время ручного тестирования одного из алгоритмов, на котором это обкатывалось, сократилось в 3-4 раза (до того мы находили несколько подходящих записей и update-или их). Разработчикам и аналитикам стало легче.Разработчики использовали мои скрипты, чтобы было на чём отлаживаться.Аналитики - для подготовки к демо. Ушла проблема разных справочников на разных стендах.Скрипт одинаково хорошо работал на всех, т.к. id-шники не зашиты хардкодом, а берутся запросами. Автоматизировать тест кейсы с такими скриптами легко и быстро.