Ограничение количества выбираемых строк при соединении



Иногда, при соединении, возникает необходимость ограничить количество выбираемых записей. О том, как это сделать…

Может, кому-то пригодится.

Есть две таблицы, в одной содержится список характеристик и предъявляемые по ним требования. В другой — список основных средств, их характеристик и те значения, которым они удовлетворяют.

 См. Рис1 и Рис2

Хm — характеристики

ЗХm — требуемые значения каждой характеристики

ОСp — основные средства

ЗXmОСp — значение определенной характеристики у определенного основного средства

 Необходимо присоединить к первой таблице вторую, по условию удовлетворения характеристикам. При этом, нужно выбирать не все строки из второй таблицы, а только определенное количество N основных средств для каждой характеристики. Т.е. не всего N, а N для первой характеристики, N — для второй и т.д. Т.е. стоит вопрос об ограничении выбираемых записей при соединении таблиц.

Таким образом, в итоге хотим получить подобную таблицу (если N = 2 и если предположить, что все указанные характеристики отвечают выставленным требованиям)

 См. Рис3

Стандартное и наиболее часто встречающееся решение проблемы — через создания в цикле запроса, в котором объединяется множество подзапросов, каждый из которых выбирает первые N для каждой характеристики.

Возникло желание придумать нечто более изящное. Получилось вот такое решение.

 

Запрос = Новый Запрос;
//объявляем менеджер временных таблиц
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
//сначала выберем только те ТС, чьи характеристики отвечают необходимым условиям
Запрос.Текст = "ВЫБРАТЬ
| ТЧ2.ОсновноеСредство КАК ОС,
| ТЧ1.Характеристика КАК Харка,
| ТЧ1.ЗначениеХарактеристики КАК ЗнХар
|ПОМЕСТИТЬ ТЗ
|ИЗ
| ТЧ1 КАК ТЧ1
| ЛЕВОЕ СОЕДИНЕНИЕ ТЧ2 КАК ТЧ2
| ПО ТЧ1.Характеристика = ТЧ2.Характеристика
| И ТЧ1.ЗначениеХарактеристики {условие} ТЧ2.ЗначениеХарактеристикиОС";
//вместо {условие} вставить то соответсвтие, которое ставиться задачей (больше, меньше, равно, между и т.п.)
Запрос.Выполнить();
//теперь собственно запрос, который отберет нам первые N записей при соединении
Запрос.Текст = "ВЫБРАТЬ
| ТЧ1.Характеристика КАК Характеристика,
| ТЧ2.ОС КАК ОС
|ИЗ
| ТЧ1 КАК ТЧ1
| ЛЕВОЕ СОЕДИНЕНИЕ ТЧ2 КАК ТЧ2
| ПО ТЧ1.Характеристика = ТЧ2.Характеристика
| И ТЧ1.ЗначениеХарактеристики {условие} ТЧ2.ЗначениеХарактеристикиОС
|ГДЕ
| ТЧ2.ОсновноеСредство В
| (ВЫБРАТЬ ПЕРВЫЕ N
| ТЗ.ОС
| ИЗ
| ТЗ
| ГДЕ
| ТЧ1.ЗначениеХарактеристики {условие} ТЗ.ЗнХар)";
//вместо {условие} вставить то соответсвтие, которое ставиться задачей (больше, меньше, равно, между и т.п.)
Результат = Запрос.Выполнить().Выгрузить();

ТЧ1 и ТЧ2 подставить справочники, документы и т.п.

P.S. Публикация первая, поэтому прошу прощения за недочеты в оформлении

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *