В собственной временной таблице три строки: две одинаковые метки с ценами 10/20 и одна строка NULL/NULL. Проверяем три разных способа подсчёта и влияние NULL на агрегаты.
Где и как запускать
Полный серверный общий модуль учебной базы. Собственные значения в памяти, без чтения или записи рабочих данных.
Подготовка
В отдельной учебной базе 8.5.1.1343 создайте общий модуль УчебныйЯзык: Сервер=Истина, Глобальный=Ложь, ВызовСервера=Ложь, Привилегированный=Ложь. Клиентские и внешнее соединение отключены; ПовторноеИспользованиеВозвращаемыхЗначений=НеИспользовать.
Вставьте весь приведённый текст в этот общий модуль. ВыполнитьПример — экспортная точка входа; остальные процедуры и функции располагаются рядом, а не внутри неё.
В своей внешней учебной обработке создайте управляемую форму, команду Выполнить и кнопку. Клиентский обработчик Выполнить(Команда) вызывает свою процедуру ВыполнитьНаСервере(); она имеет директиву &НаСервереБезКонтекста и одну строку УчебныйЯзык.ВыполнитьПример();. Это серверный вызов общего модуля, а не разрешение клиенту прямо обращаться к серверной библиотеке.
Все товары, количества и строки придуманы в этом модуле. Запись документов, подключение к чужой базе, файлы, сеть и печать не используются. В рабочие общие модули текст не вставляйте.
HTML только показывает BSL. Код в 1С не запускался; перечисленные результаты и отрицательные опыты проверяйте самостоятельно в собственном стенде.
Процедура ВыполнитьПример() Экспорт
Менеджер = Новый МенеджерВременныхТаблиц;
Попытка
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Менеджер;
Запрос.Текст = "ВЫБРАТЬ
| ""Книга"" КАК Метка,
| 10 КАК Цена
|ПОМЕСТИТЬ ВТСвоиМетки
|ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ""Книга"", 20
|ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ NULL, NULL";
Запрос.Выполнить();
Запрос.Текст = "ВЫБРАТЬ
| КОЛИЧЕСТВО(*) КАК ВсегоСтрок,
| КОЛИЧЕСТВО(Метки.Метка) КАК ЗаполненныхМеток,
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Метки.Метка) КАК РазныхМеток,
| КОЛИЧЕСТВО(Метки.Цена) КАК ЗаполненныхЦен,
| СУММА(Метки.Цена) КАК Сумма,
| СРЕДНЕЕ(Метки.Цена) КАК Среднее,
| МИНИМУМ(Метки.Цена) КАК Минимум,
| МАКСИМУМ(Метки.Цена) КАК Максимум
|ИЗ ВТСвоиМетки КАК Метки";
Итоги = Запрос.Выполнить().Выгрузить();
Если Итоги.Количество() <> 1 Тогда
ВызватьИсключение "Ожидалась одна агрегатная строка своих меток";
КонецЕсли;
Итог = Итоги[0];
Сообщить(Итог.ВсегоСтрок = 3);
Сообщить(Итог.ЗаполненныхМеток = 2 И Итог.РазныхМеток = 1);
Сообщить(Итог.ЗаполненныхЦен = 2);
Сообщить(Итог.Сумма = 30 И Итог.Среднее = 15);
Сообщить(Итог.Минимум = 10 И Итог.Максимум = 20);
Исключение
Менеджер.Закрыть();
ВызватьИсключение;
КонецПопытки;
Менеджер.Закрыть();
КонецПроцедурыРазбор по шагам
Создать свой МенеджерВременныхТаблиц. Первый запрос содержит только три явно записанные константные строки; конфигурационные источники не нужны.
ОБЪЕДИНИТЬ ВСЕ сохраняет оба экземпляра Книга. Обычное ОБЪЕДИНИТЬ могло бы устранять одинаковые строки, но здесь цены 10/20 различаются; различие операторов всё равно не подменяет КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Метка).
NULL вводится прямо в языке запросов. Не используем Неопределено или пустую строку вместо SQL NULL и не записываем NULL в типизированную строковую колонку ТаблицаЗначений с возможным преобразованием.
КОЛИЧЕСТВО(*) считает все три строки; КОЛИЧЕСТВО(Метка) — две не-NULL метки; РАЗЛИЧНЫЕ Метка — одно уникальное не-NULL значение.
КОЛИЧЕСТВО(Цена)=2, сумма 30, среднее 15. NULL не становится третьей нулевой ценой: в среднем участвуют только 10 и 20.
Минимум 10 и максимум 20 вычислены по существующим числам. Без СГРУППИРОВАТЬ ПО запрос с агрегатами формирует одну сводную строку.
До Итоги[0] проверяем одну строку. Во всех исходах закрываем только свой менеджер временных таблиц.
Как проверить результат
Пять сообщений Истина: 3 строки, 2 заполненных метки, 1 различная метка, 2 цены, сумма 30, среднее 15, минимум 10 и максимум 20.
Замените только третий NULL цены на 0: количество цен станет 3, сумма останется 30, среднее станет 10 и минимум 0. Это другое содержимое данных, не способ обхода NULL.
Замените третью NULL-метку на пустую строку: она не равна NULL и должна учитываться как отдельное строковое значение. Сначала пересчитайте проверки.
Ожидаемый результат
Три разных подсчёта проверены на собственных явных данных, без смешения NULL, нуля и пустой строки.
На что обратить внимание
Количество строк, число заполненных значений и число различных значений — три отдельных показателя.
КОЛИЧЕСТВО не применяется к ХранилищеЗначения и строкам неограниченной длины. Наши метки — короткие константные строки языка запросов.
Не считайте NULL нулём: такая подстановка меняет среднее, минимум и смысл данных.
Ожидаемые числа относятся только к этому источнику. Пример в 1С не запускался.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.