Недавно столкнулся с одной задачей, решение которой в нормальном виде нигде не описано.
Описание задачи
Есть некоторое количество данных в highload блоке. Нужно подсчитать, сколько записей имеют определённые значения в некоем столбце этой таблицы (которой является HL-блок).
Поиск решения
Самое простое решение в лоб: вызываем \Bitrix\Main\Entity\DataManager::getList, получаем все записи из highload блока и подсчитываем нужные значения средствами PHP. Это вполне рабочий вариант, но медленный. Потому что тут и база данных перебирает все строки таблицы, и цикл в PHP может работать долго, если записей миллионы.
Логично было бы использовать средства d7 вроде \Bitrix\Main\Entity\DataManager::getCount, но этот метод просто возвращает количество записей для конкретного запроса. Под изначальную задачу не подходит.
Решение
Недолгим поиском по форумам и блогам было найден нужный параметр метода \Bitrix\Main\Entity\DataManager::getList, который я как-то проглядел до этого. Параметр этот называется runtime.
В этом параметре можно указать функции, которыми БД будет оперировать с данными. При этом в документации нет примера использования для этого параметра. И в коде компонентов битрикса он упоминается буквально один-два раза. Но этого достаточно.
Нам необходимо использовать SQL функцию count, для подсчета значений. И вот как это сделать с использованием D7 и без прямых запросов к БД:
$result = НазваниеКлассаУнаследованногоОтDataManager::getList([
'filter' => ['какой-нибудь фильтр'],
//тут важно указать название столбца таблицы
//(свойства HL блока, обычно начинающегося с UF)
//по которому мы будем группировать отчет
//второй элемент, это название для столбца,
//в котором будут выведены итоговые суммы, в данном случае пусть это будет COUNT
'select' => [
'Название_поля_для_группировки',
'COUNT'
],
//сортировку можно делать по столбцу с суммами
'order' => [
'COUNT' => 'DESC'
],
//тут мы должны указать как будет считаться столбец COUNT
'runtime' => [
//в качестве ключа используется поле, которое мы указали в select
'COUNT' => [
//тут указывается тип данных, для поля.
//я встречал только примеры с integer и reference
'data_type' => 'integer',
//тут указывается функция, вроде count, max и т.п.
//важно следить за кавычками и указывать правильные имена таблицы
//(они обычно не совпадают с названиями HL блока)
'expression' => ['count(`имя_таблицы`.`поле_для_подсчета`)']
]
]
]);
В итоге мы получаем массив вида
[
'Значение поля' => 'количество',
...
]