Книга знаний

1С:Предприятие / v8 / Приемы программирования / Запросы

v8: Нумерация строк в запросе

В статье обсуждается возможность добавления в результат запроса дополнительной колонки с номерами строк, а так же возможности, которые от этого возникаютАвтор статьи: zag2art | Редакторы: Immortal
Последняя редакция №21 от 06.11.08 | История
URL: http://kb.mista.ru/article.php?id=703

Ключевые слова: нумерация строк запроса, ПЕРВЫЕ, нумерация строк в построителе, пронумеровать


Иногда возникает необходимость добавить в запрос колонку с номерами строк, например, когда нужно вывести номера строк в отчет, а используется построитель отчета. Так же нумерация строк полезна когда необходимо для определенных группировок вывести ограниченное количество строк данных. Что-то типа ПЕРВЫЕ 5 документов для каждого контрагента.

Данная статья навеяна обсуждением в: v8: Раздумья над запросом

Начнем с того, что в v8 используется ограниченный диалект SQL поэтому многие методики нумерации строк запроса, возможные в SQL, для нас не доступны. (если кому-то интересно как это делать в SQL - http://www.sql.ru/faq/faq_topic.aspx?fid=126)

Итак, есть код, выбирающий номенклатуру, отсортированный по наименованию:
[1с]
ВЫБРАТЬ
   Номенклатура.Ссылка
ИЗ
   Справочник.Номенклатура КАК Номенклатура

УПОРЯДОЧИТЬ ПО
   Номенклатура.Наименование
[/1с]исходный запрос

Требуется добавить сюда колонку с порядковыми номерами номенклатуры (в рамках данной сортировки).
[1с]
ВЫБРАТЬ
   Номенклатура.Ссылка КАК Номенклатура,
   КОЛИЧЕСТВО(Номенклатура_1.Ссылка) КАК Номер
ИЗ
   Справочник.Номенклатура КАК Номенклатура
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура_1
       ПО Номенклатура.Наименование >= Номенклатура_1.Наименование      // Условие сортировки для нумерации

СГРУППИРОВАТЬ ПО
   Номенклатура.Ссылка

УПОРЯДОЧИТЬ ПО
   Номенклатура.Наименование
[/1с]запрос с номерами строк

Соединяем таблицу саму с собой довольно хитрым способом. По правой таблице подсчитываем количество номенклатуры с наименованием меньше текущего левого, используя группировку.

Аналогичную технику можно применить, если нужно задавать нумерацию строк с учетом группировки по какому-то полю.
[1с]
ВЫБРАТЬ
   Номенклатура.Ссылка КАК Номенклатура,
   Номенклатура.Родитель КАК Родитель,
   КОЛИЧЕСТВО(Номенклатура_1.Ссылка) КАК Номер
ИЗ
   Справочник.Номенклатура КАК Номенклатура
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура_1
       ПО Номенклатура.Наименование >= Номенклатура_1.Наименование
           И Номенклатура.Родитель = Номенклатура_1.Родитель

СГРУППИРОВАТЬ ПО
   Номенклатура.Родитель,
   Номенклатура.Ссылка
[/1с]запрос с номерами строк в рамках группировки

Это тот же самый запрос, в него просто добавлена группировка по полю "Родитель", нумерация для каждого родителя своя.

Быстродействие:
Если говорить о быстродействии, то запросы подобного рода естественно ресурсоемки (математически ложность порядка N^2). Для большинства повседневных задач их использование вполне приемлемо.
Кстати, второй запрос выполняется несколько быстрее первого, это связано с меньшим размером вспомогательных таблиц.

Пример реального использования:
Теперь немного о том, ради чего всё это делается, то-есть польза, которую можно извлечь из нумерации строк запроса.

Например, перед нами стоит задача получить для каждого контрагента пять последних документов поступления товаров и услуг:
[1с]
ВЫБРАТЬ
   ПоступлениеТоваровУслуг.Контрагент КАК Контрагент,
   ПоступлениеТоваровУслуг.Ссылка КАК Ссылка,
   КОЛИЧЕСТВО(ПоступлениеТоваровУслуг_1.Ссылка) КАК Номер
ИЗ
   Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг_1
       ПО ПоступлениеТоваровУслуг.Дата <= ПоступлениеТоваровУслуг_1.Дата
           И ПоступлениеТоваровУслуг.Контрагент = ПоступлениеТоваровУслуг_1.Контрагент

СГРУППИРОВАТЬ ПО
   ПоступлениеТоваровУслуг.Ссылка,
   ПоступлениеТоваровУслуг.Контрагент

ИМЕЮЩИЕ
   КОЛИЧЕСТВО(ПоступлениеТоваровУслуг_1.Ссылка) <= 5

УПОРЯДОЧИТЬ ПО
   Контрагент,
   Номер
[/1с]
запрос с номерами строк при наличии дублей интересующего поля(того,относительно которого строится счетчик)
[1с]
ВЫБРАТЬ
   КОЛИЧЕСТВО(ФизическиеЛица_1.Наименование) КАК Номер,
   ФизическиеЛица.Ссылка КАК ФИО
ИЗ
   Справочник.ФизическиеЛица КАК ФизическиеЛица
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ФизическиеЛица КАК ФизическиеЛица_1
       ПО (ФизическиеЛица.Наименование + ФизическиеЛица.Код >= ФизическиеЛица_1.Наименование + ФизическиеЛица_1.Код)

СГРУППИРОВАТЬ ПО
   ФизическиеЛица.Ссылка

УПОРЯДОЧИТЬ ПО
   Номер
[/1с]
Собственно говоря идея какова : использовать "составное поле" для получения возрастающего итога (при этом одно поле может содержать дубли, а второе в данном примере- нет.)
Родилось в голове НЕКРОН'а

Закладка

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2011 | Mista.ru

Яндекс.Метрика