КОЛИЧЕСТВО: строки, заполненные значения и РАЗЛИЧНЫЕ

Учебные задачи

В собственной временной таблице три строки: две одинаковые метки с ценами 10/20 и одна строка NULL/NULL. Проверяем три разных способа подсчёта и влияние NULL на агрегаты.

Где и как запускать

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

Подготовка

  1. В отдельной учебной базе 8.5.1.1343 создайте общий модуль УчебныйЯзык: Сервер=Истина, Глобальный=Ложь, ВызовСервера=Ложь, Привилегированный=Ложь. Клиентские и внешнее соединение отключены; ПовторноеИспользованиеВозвращаемыхЗначений=НеИспользовать.

  2. Вставьте весь приведённый текст в этот общий модуль. ВыполнитьПример — экспортная точка входа; остальные процедуры и функции располагаются рядом, а не внутри неё.

  3. В своей внешней учебной обработке создайте управляемую форму, команду Выполнить и кнопку. Клиентский обработчик Выполнить(Команда) вызывает свою процедуру ВыполнитьНаСервере(); она имеет директиву &НаСервереБезКонтекста и одну строку УчебныйЯзык.ВыполнитьПример();. Это серверный вызов общего модуля, а не разрешение клиенту прямо обращаться к серверной библиотеке.

  4. Все товары, количества и строки придуманы в этом модуле. Запись документов, подключение к чужой базе, файлы, сеть и печать не используются. В рабочие общие модули текст не вставляйте.

  5. HTML только показывает BSL. Код в 1С не запускался; перечисленные результаты и отрицательные опыты проверяйте самостоятельно в собственном стенде.

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

Разбор по шагам

  1. Создать свой МенеджерВременныхТаблиц. Первый запрос содержит только три явно записанные константные строки; конфигурационные источники не нужны.

  2. ОБЪЕДИНИТЬ ВСЕ сохраняет оба экземпляра Книга. Обычное ОБЪЕДИНИТЬ могло бы устранять одинаковые строки, но здесь цены 10/20 различаются; различие операторов всё равно не подменяет КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Метка).

  3. NULL вводится прямо в языке запросов. Не используем Неопределено или пустую строку вместо SQL NULL и не записываем NULL в типизированную строковую колонку ТаблицаЗначений с возможным преобразованием.

  4. КОЛИЧЕСТВО(*) считает все три строки; КОЛИЧЕСТВО(Метка) — две не-NULL метки; РАЗЛИЧНЫЕ Метка — одно уникальное не-NULL значение.

  5. КОЛИЧЕСТВО(Цена)=2, сумма 30, среднее 15. NULL не становится третьей нулевой ценой: в среднем участвуют только 10 и 20.

  6. Минимум 10 и максимум 20 вычислены по существующим числам. Без СГРУППИРОВАТЬ ПО запрос с агрегатами формирует одну сводную строку.

  7. До Итоги[0] проверяем одну строку. Во всех исходах закрываем только свой менеджер временных таблиц.

Как проверить результат

  1. Пять сообщений Истина: 3 строки, 2 заполненных метки, 1 различная метка, 2 цены, сумма 30, среднее 15, минимум 10 и максимум 20.

  2. Замените только третий NULL цены на 0: количество цен станет 3, сумма останется 30, среднее станет 10 и минимум 0. Это другое содержимое данных, не способ обхода NULL.

  3. Замените третью NULL-метку на пустую строку: она не равна NULL и должна учитываться как отдельное строковое значение. Сначала пересчитайте проверки.

Ожидаемый результат

Три разных подсчёта проверены на собственных явных данных, без смешения NULL, нуля и пустой строки.

На что обратить внимание

  1. Количество строк, число заполненных значений и число различных значений — три отдельных показателя.

  2. КОЛИЧЕСТВО не применяется к ХранилищеЗначения и строкам неограниченной длины. Наши метки — короткие константные строки языка запросов.

  3. Не считайте NULL нулём: такая подстановка меняет среднее, минимум и смысл данных.

  4. Ожидаемые числа относятся только к этому источнику. Пример в 1С не запускался.

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

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.