1с запрос посчитать сумму

Обновлено: 05.07.2024

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

Методическая рекомендация (полезный совет)

1. Если в операции деления заранее известны порядки числителя и знаменателя, то следует по возможности избегать выполнения деления числа заведомого маленького порядка на число заведомо большого порядка. Например, вместо:

0.02 / 28346 * 9287492

0.02 * 9287492 / 28346

2. При выполнении арифметических операций в запросах к базе данных платформа 1С:Предприятия поддерживает точность вычислений до 8 разрядов дробной части. Однако, из-за особенностей работы различных СУБД в некоторых ситуациях точность результатов может отличаться от 8. Более подробно о вычислении разрядности результатов можно почитать в статье ИТС Разрядность результатов выражений и агрегатных функций в языке запросов.

Если точность результата выполнения запроса к базе данных, содержащего

  • арифметические операции деления,
  • агрегатные функции СРЕДНЕЕ ,
  • арифметические операции умножения, если каждый из множителей может иметь дробную часть,

различается на различных СУБД, то рекомендуется к операндам и/ или результатам этих операций применять оператор явного приведения разрядности и точности числовых данных:

ВЫРАЗИТЬ(. КАК Число(m, n))

Оператор ВЫРАЗИТЬ следует применять к операндам, если на какой-нибудь СУБД точность получаемого результата недостаточна. Например, требуется 10 разрядов после запятой, а получается 6.

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

ВЫБРАТЬ
ВЫРАЗИТЬ(Таблица.Множитель * Таблица.Числитель КАК Число(25,10)) / ВЫРАЗИТЬ(Таблица.Знаменатель КАК Число(15,10)) КАК Результат
ИЗ Таблица КАК Таблица

Оператор ВЫРАЗИТЬ следует применять к результату, если точность вычислений на всех СУБД достаточна, но на некоторых она больше, а на других меньше. При этом указанная общая разрядность результата должна быть минимальной, но не меньше той, которая достаточна для представления значений результата. Если в приведенном примере известно, что Знаменатель не может быть меньше 0.00001, то для представления результата достаточно 20 разрядов целой части. В этом случае выражение может быть записано так:

ВЫБРАТЬ
ВЫРАЗИТЬ(Таблица.Множитель * Таблица.Числитель / Таблица.Знаменатель КАК Число(30,10)) КАК Результат
ИЗ Таблица КАК Таблица

Иногда может быть целесообразно выполнить приведения к требуемой точности как операндов, так и результата. Например:

ВЫБРАТЬ
ВЫРАЗИТЬ(ВЫРАЗИТЬ(Таблица.Множитель * Таблица.Числитель КАК Число(25,10)) / ВЫРАЗИТЬ(Таблица.Знаменатель КАК Число(15,10)) КАК Число(30,10)) КАК Результат
ИЗ Таблица КАК Таблица

В языке определены следующие виды арифметических операций.

  • Сложение (Оп1 + Оп2)
  • Вычитание (Оп1 — Оп2)
  • Умножение (Оп1 * Оп2)
  • Деление (Оп1 / Оп2)
  • Остаток от деления (Оп1 % Оп2)
  • Унарный минус (-Оп1)

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

Сложение определено для следующих типов операндов:

Дата + Число (к дате прибавляется число секунд)

Вычитание определено для следующих типов операндов:

Дата — Число (от даты отнимается число секунд)

Дата — Дата (результатом является разница между двумя датами, измеренная в секундах)

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

Математические выражения используются в правой части оператора присваивания, а также в качестве параметров процедур и функций

Во встроенном языке определены арифметические операции двух видов:

Унарные арифметические операции

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

Унарный минус определен только для типа Число . Во всех остальных случаях будет выдано исключение « Операция получения отрицательного значения не определена для строковой величины »

Бинарные арифметические операции

Операция сложения
Данная арифметическая операция выполняет добавление значения второго операнда к значению первого. При этом тип значения получаемого результата определяется типом первого операнда. Если тип второго операнда не совпадает с типом первого, выполняется неявное преобразование типов.

Применимость операции сложения:

ОперандА ОперандБ Результат Комментарий
Число Число, Строка, Дата Число
Дата Число Дата К исходной дате добавляется количество дней, заданное вторым оператором
Строка Строка, Число, Дата Строка К исходной строке добавляются все символы второй. Длина конечной строки определяется суммой длин обеих строк. Такую операцию называют еще конкатенацией строк

Операция вычитания

Данная арифметическая операция выполняет вычитание значения второго операнда из значения первого. При этом тип значения получаемого результата определяется типом первого операнда. Если тип второго операнда не совпадает с типом первого, выполняется неявное преобразование типов.

Применимость операции вычитания:

ОперандА ОперандБ Результат Комментарий
Число Число, Строка, Дата Число
Дата Число Дата От исходной даты отнимается количество дней, заданное вторым оператором
Дата Дата Число Вычисляется количество дней на которое первая дата больше второй

Операция умножения

Данная арифметическая операция выполняет умножение значения первого операнда на значение второго. Операция применима только для типа Число . Если тип второго операнда не совпадает с типом первого, выполняется неявное преобразование типов.

Операция деления

Данная арифметическая операция выполняет деление значения первого операнда на значение второго. Операция применима только для типа Число . Если тип второго операнда не совпадает с типом первого, выполняется неявное преобразование типов.

Остаток от деления

Данная арифметическая операция вычисляет остаток от деления значения первого операнда на значение второго. Операция применима только для типа Число . Если тип второго операнда не совпадает с типом первого, выполняется неявное преобразование типов. Следует учитывать, что оба операнда операции округляются до целого значения.

Приоритет выполнения арифметических операций

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

  1. Унарный минус;
  2. Умножение, деление, остаток от деления;
  3. Сложение и вычитание;

Для того, чтобы повлиять на порядок вычислений можно использовать круглые скобки.

Войдите как ученик, чтобы получить доступ к материалам школы

Язык запросов 1С 8.3 для начинающих программистов: группировка

Автор уроков и преподаватель школы: Владимир Милькин

Группировка в запросах

Давайте запросим из таблицы Справочник.Еда следующие реквизиты: Наименование, Цвет и Калорийность:

01

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

Алгоритм для жёлтого цвета будет такой:

  1. Находим все строчки у которых в поле Цвет стоит Жёлтый.
  2. Это будут строчки №1, 6, 8 и 9.
  3. Суммируем поле Калорийность для каждой из этих строк: 89 + 31 + 340 + 536
  4. Получаем, что для жёлтого цвета суммарная калорийность равна 996.

И так для каждого цвета.

Описанный выше процесс называется группировкой . Таким образом, группировка - это "схлопывание" (свёртка) строчек таблицы по определенному признаку.

При группировке все поля делятся на две группы:

  • Группировочные - это как раз те поля, по которым идёт свёртка. В нашем случае таким полем является Цвет.
  • Группируемые - это те поля, которые сворачиваются (схлопываются, объединяются). В нашем случае таким полем является Калорийность.

01

Группируемые поля не могут быть сами по себе. К ним обязательно применяется одна из агрегатных функций: СУММА, СРЕДНЕЕ, МИНИМУМ, МАКСИМУМ, КОЛИЧЕСТВО, КОЛИЧЕСТВО РАЗЛИЧНЫЕ:

02

Агрегатная функция СУММА

Это как раз случай, который мы разбирали. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь. Все строки группируются по группировочным полям (Цвет), а группируемые поля (Калорийность) суммируются:

сумма

Агрегатная функция СРЕДНЕЕ

В этом случае все строки группируются по группировочным полям (Цвет), а среди группируемых полей (Калорийность) находится среднее значение:

среднее

Агрегатная функция МИНИМУМ

В этом случае все строки группируются по группировочным полям (Цвет), а среди группируемых полей (Калорийность) находится минимальное значение:

минимум

Агрегатная функция МАКСИМУМ

В этом случае все строки группируются по группировочным полям (Цвет), а среди группируемых полей (Калорийность) находится максимальное значение:

максимум

Агрегатная функция КОЛИЧЕСТВО

В этом случае все строки группируются по группировочным полям (Цвет), а среди группируемых полей (Калорийность) находится их количество :

количество

Агрегатная функция КОЛИЧЕСТВО РАЗЛИЧНЫЕ

В этом случае все строки группируются по группировочным полям (Цвет), а среди группируемых полей (Калорийность) находится количество элементов с различными значениями:

количество различные

Функция КОЛИЧЕСТВО РАЗЛИЧНЫЕ требует пояснения, потому что на выбранном примере её результат совпадает с функцией КОЛИЧЕСТВО. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь. Вот более показательный пример, который всё объясняет:

03

Группировка без группируемых полей и агрегатных функций

Использование агрегатных функций в запросе не требуется, если результатом запроса будут только группировочные поля:

06

К примеру, сделаем выборку всех вкусов, которые встречаются среди еды:

Как видите вкусы повторяются - давайте их сгруппируем:

Таким образом, мы сделали группировку только по группировочным полям (Вкус). Группируемые поля, а следовательно и агрегатные функции нам не понадобились.

Группировка без группировочных полей

Соответственно использование группировочных полей также не требуется, если результатом запроса будут только группируемые поля:

12

К примеру, получим результаты агрегатных функций применительно к полю Калорийность без группировочных полей (то есть по всей таблице):

13

Группировка по нескольким полям

Группировочных (как впрочем и группируемых) полей может быть сколь угодно много. В запросе они перечисляются через запятую.

Использование произвольных выражений в итогах языка запроса

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

Произвольные выражения в итогах

Синтаксис и функциональность выражения для расчета итогов аналогичны простому выражению языка запроса, однако имеются некоторые особенности:

  • в выражениях для расчета итогов нельзя использовать операции В и В ИЕРАРХИИ со вложенными запросами.
  • в выражениях для расчета итогов результат функции Представление() может быть использован в другом выражении.

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

ИТОГИ
100 * Сумма(Прибыль) / СУММА(Оборот) КАК ПроцентПрибыли

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

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

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

ИТОГИ
Номенклатура КАК Номенклатура,// Правильно, т.к. поле присутствует в списке группировок итогов
СуммаОборот КАК СуммаОборот, // Неправильно, т.к. поле отсутствует в списке группировок итогов
Сумма(КоличествоОборот) КАК КоличествоОборот // Правильно, т.к. поле используется в агрегатной функции
ПО
Номенклатура,
Контрагент

В случае если поле - группировка используется в итоговом выражении, и по данному полю еще не было получена группировка - значение поля будет равняться NULL .

Примеры использования

Расчет выражений от агрегатных функций

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

ВЫБРАТЬ
Номенклатура,
СуммаОборот КАК Оборот,
СуммаПрибыль КАК Прибыль,
100 * СуммаПрибыль / СуммаОборот КАК ПроцентПрибыли
ИЗ
РегистрНакопления.УчетПрибыли.Обороты
ИТОГИ
СУММА(Оборот),
СУММА(Прибыль),
100 * СУММА(Прибыль) / СУММА(Оборот) КАК ПроцентПрибыли
ПО
Номенклатура ИЕРАРХИЯ

В данном примере в поле "ПроцентПрибыли" итоговых записей будет помещено значение суммы по полю "Прибыль" умноженное на 100 и поделенное на значение суммы по полю "Оборот".

Расчет итогов только для уже полученных группировок

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

ВЫБРАТЬ
ОсновнойОстатки.Счет КАК Счет,
ОсновнойОстатки.Валюта КАК Валюта,
ОсновнойОстатки.СуммаОстаток КАК СуммаОстаток,
ОсновнойОстатки.ВалютнаяСуммаОстаток КАК ВалютнаяСуммаОстаток
ИЗ
РегистрБухгалтерии.Основной.Остатки КАК ОсновнойОстатки
ИТОГИ
СУММА(СуммаОстаток),
ВЫБОР
КОГДА Валюта ЕСТЬ НЕ NULL
ТОГДА СУММА(ВалютнаяСуммаОстаток)
КОНЕЦ КАК ВалютнаяСуммаОстаток
ПО
Счет,
Валюта

В данном примере значение итога для поля "ВалютнаяСуммаОстаток" будет рассчитано только для итоговых записей, в которых уже получена группировка Валюта. Т.е. в итоговых записях для группировки Счет итоги по полю "ВалютнаяСуммаОстаток" будут рассчитывать только тогда, когда итоги по данной группировке будут получаться только внутри группировки Валюта.

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

ВЫБРАТЬ
ОсновнойОстатки.Счет КАК Счет,
ОсновнойОстатки.Валюта КАК Валюта,
ОсновнойОстатки.СуммаОстаток КАК СуммаОстаток,
ОсновнойОстатки.ВалютнаяСуммаОстаток КАК ВалютнаяСуммаОстаток
ИЗ
РегистрБухгалтерии.Основной.Остатки КАК ОсновнойОстатки
ИТОГИ
СУММА(СуммаОстаток),
ВЫБОР
КОГДА КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Валюта) = 1
ТОГДА СУММА(ВалютнаяСуммаОстаток)
КОНЕЦ КАК ВалютнаяСуммаОстаток
ПО
Счет,
Валюта

В данном примере рассчет итого по полю "ВалютнаяСуммаОстаток" будет производиться только для тех итоговых записей, которые содержат лишь одно значение поля "Валюта".

Переопределение представлений для группировок

В случае если поле является представлением поля группировки, переопределение выражения для данного поля приведет к тому, что в результат, в качестве представления поля, будет выведен результат выражения итога. Используя данную особенность, возможно переопределить представления для группировок.

ВЫБРАТЬ
ПродажиОбороты.Номенклатура КАК Номенклатура,
ПродажиОбороты.Номенклатура.Код КАК НоменклатураКод,
ПРЕДСТАВЛЕНИЕ(ПродажиОбороты.Номенклатура) КАК НоменклатураПредставление,
ПродажиОбороты.КоличествоОборот КАК КоличествоОборот,
ПродажиОбороты.СуммаОборот КАК СуммаОборот
ИЗ
РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ИТОГИ
НоменклатураКод + ") " + НоменклатураПредставление КАК НоменклатураПредставление,
СУММА(КоличествоОборот),
СУММА(СуммаОборот)
ПО
Номенклатура

В данном примере, в качестве представления поля "Номенклатура" в итоговых записях, будет использоваться выражение, состоящее из кода и основного представления.

Разрядность результатов выражений и агрегатных функций в языке запросов

При использовании в запросах операций и функций над данными, в определение которых входят спецификации длины ( Строка , Число ) и точности ( Число ), бывает необходимо учитывать правила вычисления длины и точности результатов. Этот раздел содержит описание соответствующих правил.

Операции над строками

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

ПОДСТРОКА(Строка, m, k) Неограниченная длина Длина k, переменная Длина k, переменнаяМИНИМУМ(Строка) Неограниченная длина Длина n, фиксированная Длина n, переменнаяМАКСИМУМ(Строка) Неограниченная длина Длина n, фиксированная Длина n, переменная

В следующей таблице приведены правила определения дополнительных спецификаций результата операции "+" (конкатенация строк), имеющей 2 строковых операнда.

Неограниченная длина Неограниченная длина Неограниченная длина Неограниченная длинаДлина n Фиксированная Неограниченная длина Длина n + m фиксированная Длина n + m переменнаяПеременная Неограниченная длина Длина n + m переменная Длина n + m переменная

Операции над числами

Выполняя различные преобразования числовых данных, необходимо учитывать, что максимальное количество цифр, которое может содержать число (его целая и дробная часть вместе), равно 38 цифр. 1С:Предприятие использует десятичные числа с фиксированной точкой. Это значит, например, что число 34.28 содержит 4 цифры, число 0.00000001 содержит 8 цифр (незначащий 0 перед точкой за цифру не считается), а число 3200000000 содержит 10 цифр. Разрядность результатов различных операций вычисляется так, чтобы по возможности исключить арифметические переполнения, и в то же время максимально сохранить точность значений. При разработке конфигураций выбор разрядности полей объектов метаданных должен определяться возможной разрядностью хранимых в них данных и не должен учитывать возможное увеличение разрядности после выполнения арифметических операций и функций.

"+" (сложение), "-" (вычитание)

Операции сложения и вычитания в языке запросов всегда выполняются точно. Для этого длина дробной части результата определяется как максимальная из длин дробных частей операндов. Длина целой части результата как максимальная из длин целых частей операндов, увеличенная на 1. Если при этом общее количество цифр целой и дробной части превысит 38, то оно будет приведено к 38 за счет уменьшения числа цифр дробной части, но не менее, чем до 8.

"*" (умножение)

Операции умножения выполняется точно в том случае, если хотя бы один ее операнд является целым числом. Длина дробной части результата определяется как наибольшая из длин дробных частей операндов, но не менее 8 цифр. Длина целой части результата вычисляется как сумма длин целых частей операндов. Если при этом общее количество цифр целой и дробной части превысит 38, то оно будет приведено к 38.

При умножении двух чисел разрядность результата вычисляется следующим образом: количество разрядов целой части содержит сумму количеств разрядов целых частей операндов; количество разрядов дробной части содержит сумму количеств разрядов дробных частей операндов. Если суммарное количество разрядов (целой и дробной части) результата превышает максимально допустимое (38 - для всех СУБД кроме DB2, для DB2 - 31), то происходит балансировка точности. В этом случае операнды приводятся к разрядности, позволяющей сохранить необходимую точность операции. Например, при умножении полей (не констант) ЧИСЛО(17,4) и ЧИСЛО(27,4) платформа приведет операнды к типу ЧИСЛО(15,4) и ЧИСЛО(22,4), что в результате даст тип ЧИСЛО(37,8), не превышающий максимальное количество разрядов в СУБД. Однако, если какой-либо из операндов не поместится в соответствующую разрядность, то будет ошибка СУБД во время исполнения запроса

"/" (деление)

Операция деления выполняется точно только если оба операнда являются целыми числами, и первый операнд делится на второй без остатка. Длина дробной части результата определяется как максимальная из длин дробных частей операндов, но не менее 8 цифр. Длина целой части результата равна сумме длин целой части делимого и дробной части делителя. Если при этом общее количество цифр целой и дробной части превысит 38, то оно будет приведено к 38 за счет уменьшения числа цифр дробной части, но не менее, чем до 8.

СУММА

Агрегатная функция СУММА вычисляется по возможности точно. Количество цифр дробной части результата равно количеству цифр дробной части операнда. Количество цифр целой части увеличивается на 7 цифр. Если при этом общее количество цифр целой и дробной части превысит 38, то оно будет приведено к 38 за счет уменьшения числа цифр дробной части, но не менее, чем до 8.

МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ

Результат функций МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ имеет такое же количество цифр в целой и дробной частях, как и их операнд.

КОЛИЧЕСТВО, ГОД, КВАРТАЛ, МЕСЯЦ, ДЕНЬГОДА, ДЕНЬ, НЕДЕЛЯ, ДЕНЬНЕДЕЛИ, ЧАС, МИНУТА, СЕКУНДА, РАЗНОСТЬДАТ

Перечисленные функции имеют числовой результат с 10 цифрами в целой части. Дробная часть отсутствует.

Проблемные ситуации

Если при работе запроса возникает ошибка СУБД, следует изменить запрос, приводящий к ошибке: с помощью операции ВЫРАЗИТЬ можно привести разрядность операндов к такому виду, чтобы в результате расчета разрядности умножения платформа 1С:Предприятие не проводила автоматическую балансировку точности.

Например: привести разрядность операндов к типам ЧИСЛО(17,4) и ЧИСЛО(20,4) - в этом случае результатом умножения будет разрядность ЧИСЛО(37,8), что не превышает максимально допустимую разрядность для используемой СУБД.

Читайте также: