Yandex Metrika
sanches.free 1 просмотр

SQL в Битрикс: календарь по инфоблоку и отчёт по заказам

Где живёт запрос в проекте

ORM и DataManager в D7 удобны для поддерживаемых выборок, но иногда нужен текст SQL целиком: для отладки, разовых отчётов или когда проще описать задачу агрегатом над знакомыми таблицами ядра. Итоговую строку, которую строит ORM, имеет смысл сверять через механизмы логирования или отладки запросов в вашей среде — так вы не смешиваете «предположение о полях» с фактическим WHERE.

Дни месяца, когда в инфоблоке есть публикации

Типичная задача для календаря новостей: из таблицы b_iblock_element собрать уникальные номера дней внутри диапазона дат. Ниже пример на глобальном $DB с подстановкой границ периода и идентификатора инфоблока — подставьте свои идентификаторы и формат даты; для продакшена надёжнее прогонять литералы через хелпер экранирования подключения, а не вставлять «как есть» из пользовательского ввода.

global $DB;

$hubIblockKey = 12;
$rangeStartSql = $windowStartUtc->format('Y-m-d 00:00:00');
$rangeEndSql = $windowEndUtc->format('Y-m-d 23:59:59');

$statement = sprintf(
    'SELECT DISTINCT EXTRACT(DAY FROM `ACTIVE_FROM`) AS calendar_day_snippet '
    . 'FROM `b_iblock_element` '
    . 'WHERE `IBLOCK_ID` = %d AND `ACTIVE` = \'Y\' '
    . 'AND `ACTIVE_FROM` BETWEEN \'%s\' AND \'%s\'',
    (int)$hubIblockKey,
    $rangeStartSql,
    $rangeEndSql
);

$resultSet = $DB->Query($statement, false);
$pickedDays = [];
if ($resultSet && $resultSet->SelectedRowsCount() > 0) {
    while ($tuple = $resultSet->Fetch()) {
        $pickedDays[] = (int)$tuple['calendar_day_snippet'];
    }
}

return $pickedDays;

Заказы по партнёрам через свойства

Ниже — схема отчёта: считаются заказы с площадки с кодом сайта из Sale, где по одному свойству заказа отфильтрованы «технические» оформления, а по другому извлекается ключ партнёра, который сопоставлен с элементом отдельного инфоблока справочника. Числовые константы ORDER_PROPS_ID, код LID, IBLOCK_ID и порог даты замените на значения своей базы.

SELECT partner_element.NAME AS partner_label, COUNT(*) AS order_cnt
FROM b_sale_order AS shop_order_row
JOIN b_sale_order_props_value AS pv_partner_key
    ON pv_partner_key.ORDER_ID = shop_order_row.ID
   AND pv_partner_key.ORDER_PROPS_ID = 7
JOIN b_sale_order_props_value AS pv_exclude_tech_flag
    ON pv_exclude_tech_flag.ORDER_ID = shop_order_row.ID
   AND pv_exclude_tech_flag.ORDER_PROPS_ID = 20
   AND pv_exclude_tech_flag.VALUE = 'N'
JOIN b_iblock_element AS partner_element
    ON partner_element.IBLOCK_ID = 46
   AND partner_element.XML_ID = pv_partner_key.VALUE
WHERE shop_order_row.DATE_INSERT >= '2018-01-01 00:00:00'
  AND shop_order_row.LID = 'pa'
GROUP BY partner_element.NAME
ORDER BY partner_element.NAME;

На что смотреть после написания

  • Согласуйте имена столбцов и префиксы таблиц с версией модуля: в смешанной среде статистика может жить на реплике только для чтения.
  • Не оставляйте конкатенацию дат из внешнего ввода — используйте биндинги или хотя бы forSql того же слоя доступа.
  • Если запрос становится узким местом, вынесите тяжёлые выборки в фон или материализованный учёт показателей, а не усложняйте шаблоны витрины.

Не хотите копаться сами?

Починю за 1-3 дня. Без предоплаты — оплата по результату.

15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии