Удаление дублей запросом

03.04.14

Разработка - Запросы

Удаляем дубли запросом (из его временной таблицы). Дубли определяем по набору полей сверки. Процедура для обычных форм.

Иногда возникает необходимость убрать дубли из результата запроса. Причём делать это хочется при помощи запроса - так быстрее (критично на больших объёмах данных).

Дубли имеются в виду частичные - т.е. это такие записи, где значения, скажем, по 3 полям совпадают (у двух или более записей), а по остальным полям - нет. Я назвал такие совпадающие поля условно "поля сверки дублей". В общем-то, их может быть сколько угодно - не обязательно именно 3.

Я написал процедуру, убирающую дубли запросом. Она принимает на входе временную таблицу запроса, из которой надо удалить дубли, список полей сверки дублей. Результат помещается в новую временную таблицу того же запроса. Опционально она может показать найденные дубли (и даже вывести их на экран в печатной таблице). Вот код этой процедуры:

Она проверена в 1С:Бухгалтерия 2.5, в ЗУП, возможно, потребуется исправить "ОбщегоНазначения" на "ОбщегоНазначенияЗК".

// Процедура удаления дублей из временной таблице запроса (только для обычных форм).

// Параметры:

// "Запрос" - запрос, содержащий временную таблицу, из которой надо удалить дубли.

// "ИмяВТВход" - имя временной таблицы запроса, из которой надо удалить дубли. Удаляется после проработки процедуры (как более не нужная).

// "ПоляСверкиДубля" - строка вида "Поле1,Поле2,Поле3", содержащая имена тех полей из "ИмяВТВход", по которым мы будем искать дубли.

// "ИмяВТВыход" - имя временной таблицы запроса, в которую помещается результат работы процедуры - т.е. "ИмяВТВход", откуда убрали все дубли.

// "ОставитьВТДубли" - оставить или нет временную таблицу с обнаруженными дублями после проработки процедуры. 

// "ПоказыватьДубли" - выводить или нет печатную таблицу с обнаруженными дублями.

// "ЗаголовокТаблицыДублей" - заголовок для печатной таблицы "ПоказыватьДубли".

Процедура УдалитьДублиВТ(Запрос, ИмяВТВход, ПоляСверкиДубля, ИмяВТВыход, ОставитьВТДубли = Ложь, ПоказыватьДубли = Ложь, ЗаголовокТаблицыДублей = "Таблица найденных дублей")
	//Прототип: http://www.forum.mista.ru/topic.php?id=550537
	
	МПСД = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(ПоляСверкиДубля,",");
	
	ПоляЗапроса = "";
	
	ПоляСоединения = "";
	
	Для каждого Элем Из МПСД Цикл
		
		ПоляЗапроса = ПоляЗапроса + ИмяВТВход + "." + Элем + ", ";
		
		ПоляСоединения = ПоляСоединения + "(" + ИмяВТВход + "." + Элем + " = " + "ВТ_ДУБЛИ1." + Элем + ") И ";
	
	КонецЦикла;
	
	ПоляЗапроса = Лев(ПоляЗапроса, СтрДлина(ПоляЗапроса)-2);
	
	ПоляСоединения = Лев(ПоляСоединения, СтрДлина(ПоляСоединения)-3);
	
	Запрос.Текст = "ВЫБРАТЬ СУММА(1) КАК КоличествоДублей, " + ПоляЗапроса + " ПОМЕСТИТЬ ВТ_ДУБЛИ ИЗ " + ИмяВТВход + " КАК " + ИмяВТВход + 
	" СГРУППИРОВАТЬ ПО " + ПоляЗапроса + " ИМЕЮЩИЕ СУММА(1) > 1 ; ВЫБРАТЬ ВТ_ДУБЛИ.*, 1 КАК СтрокаДубля ПОМЕСТИТЬ ВТ_ДУБЛИ1 ИЗ ВТ_ДУБЛИ КАК ВТ_ДУБЛИ; ";
	
	Запрос.Текст = Запрос.Текст + "ВЫБРАТЬ " + ИмяВТВход + ".*, ЕСТЬNULL(ВТ_ДУБЛИ1.СтрокаДубля,0) КАК СтрокаДубля ПОМЕСТИТЬ ВТ_ВЫХОД ИЗ " + ИмяВТВход + " КАК " + ИмяВТВход +
	" ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ДУБЛИ1 КАК ВТ_ДУБЛИ1 ПО " + ПоляСоединения + " ГДЕ ВТ_ДУБЛИ1.СтрокаДубля ЕСТЬ NULL";
	
	Запрос.Выполнить();
	
	Если ПоказыватьДубли Тогда
		
		ДанныеТаблицы = Новый Запрос;
		ДанныеТаблицы.МенеджерВременныхТаблиц = Запрос.МенеджерВременныхТаблиц;
		ДанныеТаблицы.Текст =
		"Выбрать 0 КАК НомерСтроки, *
		|    Из ВТ_ДУБЛИ
		|";
		
		ТЗДубли = ДанныеТаблицы.Выполнить().Выгрузить();
		
		Для Сч = 0 По ТЗДубли.Количество()-1 Цикл
			
			ТЗДубли[Сч].НомерСтроки = Сч + 1;
		
		КонецЦикла;
		
		Построитель=Новый ПостроительОтчета(); 
		Построитель.ИсточникДанных=Новый ОписаниеИсточникаДанных(ТЗДубли); 
		Построитель.ТекстЗаголовка = ЗаголовокТаблицыДублей;
		Построитель.Вывести();
		
	КонецЕсли; 
	
	ДанныеТаблицы = Новый Запрос;
	ДанныеТаблицы.МенеджерВременныхТаблиц = Запрос.МенеджерВременныхТаблиц;
	ДанныеТаблицы.Текст =
	"Выбрать ПЕРВЫЕ 1 *
	|    Из ВТ_ВЫХОД
	|";
	
	ТЗВыход = ДанныеТаблицы.Выполнить().Выгрузить();	
	
	ПоляЗапроса = "";
	
	Для каждого Колонка Из ТЗВыход.Колонки Цикл
		
		Если Колонка.Имя <> "СтрокаДубля" Тогда
			
			ПоляЗапроса = ПоляЗапроса + Колонка.Имя + ", ";
		
		КонецЕсли;
	
	КонецЦикла; 
	
	ПоляЗапроса = Лев(ПоляЗапроса, СтрДлина(ПоляЗапроса)-2);
	
	Запрос.Текст = "ВЫБРАТЬ " + ПоляЗапроса + " ПОМЕСТИТЬ " + ИмяВТВыход + " ИЗ ВТ_ВЫХОД; УНИЧТОЖИТЬ " + ИмяВТВход + 
	"; УНИЧТОЖИТЬ ВТ_ВЫХОД; УНИЧТОЖИТЬ ВТ_ДУБЛИ1";
	
	Если НЕ ОставитьВТДубли Тогда
		
		Запрос.Текст = Запрос.Текст + "; УНИЧТОЖИТЬ ВТ_ДУБЛИ";
	
	КонецЕсли;
	
	Запрос.Выполнить();	
	
КонецПроцедуры

Удаление дублей запросом

См. также

SALE! 20%

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

13000 10400 руб.

02.09.2020    122223    673    389    

715

Для чего используют конструкцию запроса "ГДЕ ЛОЖЬ" в СКД на примере конфигурации 1С:ERP

Запросы СКД Платформа 1С v8.3 Запросы Система компоновки данных 1С:ERP Управление предприятием 2 Бесплатно (free)

В типовых конфигурациях разработчики компании 1С иногда используют в отчетах, построенных на СКД, такую конструкцию, как "ГДЕ ЛОЖЬ". Такая конструкция говорит о том, что данные в запросе не будут получены совсем. Для чего же нужен тогда запрос?

13.02.2024    5750    KawaNoNeko    23    

23

Набор-объект для СКД по тексту или запросу

Запросы СКД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    2004    2    Yashazz    0    

29

Запрос 1С copilot

Инструментарий разработчика Запросы Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Пишем на человеческом языке, что нам надо, и получаем текст запроса на языке 1С. Используются большие языковые модели (LLM GPT) от OpenAI или Яндекс на выбор.

5 стартмани

15.01.2024    6293    31    mkalimulin    25    

50

PrintWizard: поддержка представлений ЗУП в конструкторе

Инструментарий разработчика Запросы Платформа 1С v8.3 Бесплатно (free)

Одной из интересных задач, стоящих в процессе разработки, была поддержка механизма представлений в ЗУП. Но не просто возможность исполнения запросов с ними. Основная проблема была в том, чтобы с ними было удобно работать, а именно: создавать, модифицировать и отлаживать. Кратко о том, что в итоге получилось...

14.12.2023    1742    vandalsvq    7    

29

Объектная модель запроса "Схема запроса" 2

Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

Далеко уже не новый тип данных "Схема запроса". Статья о том, как использовать его "попроще". Примеры создания текста запроса с нуля и изменение имеющегося запроса.

06.12.2023    5391    user1923546    26    

43

Начните уже использовать хранилище запросов

HighLoad оптимизация Запросы

Очень немногие из тех, кто занимается поддержкой MS SQL, работают с хранилищем запросов. А ведь хранилище запросов – это очень удобный, мощный и, главное, бесплатный инструмент, позволяющий быстро найти и локализовать проблему производительности и потребления ресурсов запросами. В статье расскажем о том, как использовать хранилище запросов в MS SQL и какие плюсы и минусы у него есть.

11.10.2023    16190    skovpin_sa    14    

98
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. mikhailovaew 127 14.04.14 16:27 Сейчас в теме
зачем так сложно? если дубли не нужны, пишем ВЫБРАТЬ РАЗЛИЧНЫЕ
Alex Star; +1 Ответить
2. prodines 107 17.04.14 15:41 Сейчас в теме
(1) mikhailovaew, в этом случае будут убраны лишь дублирующиеся записи, а дубли - нет. Это разные вещи.

Дубль - это множество записей с одинаковыми полями сверки, всегда содержащее как минимум 2 элемента (на то они и есть дубли, что их больше одного). Дублей в выборке может быть сколько угодно.

Ваш вариант в каждом дубле оставит одну запись, а остальные (дублирующиеся) уберёт. Мой вариант в каждом дубле не оставит ни одной записи.
Оставьте свое сообщение