ragnar_ok
@ragnar_ok

Bitrix ORM: Как получить элементы с нулевым CNT?

Дан инфоблок с квартирами, инфоблок с планировками и инфоблок с домами. Связь свойством "Привязка к элемнтам инфоблока" идет от квартир к планировкам и от планировок к домам. Нужно получить все дома, у которых все квартиры "ACTIVE" => "N".

Для этого составил такой объект Query:

$queryObj = ElementTable::query()
    ->where([
        ['IBLOCK.CODE', 'apartments'], ['ACTIVE', 'Y'], // получаю только активные элементы из инфоблока "Квартиры"
        ['APARTMENT_PROPERTY.CODE', 'LAYOUTS_ID'], // получаю только свойство с кодом LAYOUTS_ID (привязка к эл. инфоблока "Квартиры")
        ['LAYOUT_PROPERTY.CODE', 'COMPLEX_ID'], // получаю только свойство с кодом COMPLEX_ID (привязка к эл. инфоблока "Планировки")
    ])

    ->registerRuntimeField(new Reference( // получаю таблицу свойств инфоблока "Квартиры"
        'APARTMENT_PROPERTY',
        PropertyTable::class,
        Join::on('this.APARTMENT_ELEMENT_PROPERTY.IBLOCK_PROPERTY_ID', 'ref.ID')
    ))
    ->registerRuntimeField(new Reference( // получаю таблицу значений свойств инфоблока "Квартиры"
        'APARTMENT_ELEMENT_PROPERTY',
        ElementPropertyTable::class,
        Join::on('this.ID', 'ref.IBLOCK_ELEMENT_ID')
    ))

    ->registerRuntimeField(new Reference( // получаю таблицу элементов инфоблока "Планировки"
        'LAYOUT',
        ElementTable::class,
        Join::on('this.APARTMENT_ELEMENT_PROPERTY.VALUE', 'ref.ID')
    ))
    ->registerRuntimeField(new Reference( // получаю таблицу свойств инфоблока "Планировки"
        'LAYOUT_PROPERTY',
        PropertyTable::class,
        Join::on('this.LAYOUT_ELEMENT_PROPERTY.IBLOCK_PROPERTY_ID', 'ref.ID')
    ))
    ->registerRuntimeField(new Reference( // получаю таблицу значений свойств инфоблока "Планировки"
        'LAYOUT_ELEMENT_PROPERTY',
        ElementPropertyTable::class,
        Join::on('this.LAYOUT.ID', 'ref.IBLOCK_ELEMENT_ID')
    ))

    ->addSelect('LAYOUT_ELEMENT_PROPERTY.VALUE', 'COMPLEX_ID') // получаю ID домов с активными квартирами. Указываю alias "COMPLEX_ID"
    ->addSelect(new ExpressionField('CNT', 'COUNT(%s)', 'LAYOUT_ELEMENT_PROPERTY.VALUE')) // считаю количество активных квартир
;

var_dump($queryObj->fetchAll());


Мне кажется, что лучше было бы получить сделать фильтр по CNT => 0. Но проблема в том, что в результатах нет дома с CNT => 0 из-за того, что у меня фильтр по ACTIVE => N. Как-то можно решить эту проблему?

Соответственно запрос:

SELECT 
	`iblock_element_layout_element_property`.`VALUE` AS `COMPLEX_ID`,
	COUNT(`iblock_element_layout_element_property`.`VALUE`) AS `CNT`
FROM `b_iblock_element` `iblock_element` 
LEFT JOIN `b_iblock_element_property` `iblock_element_apartment_element_property` ON `iblock_element`.`ID` = `iblock_element_apartment_element_property`.`IBLOCK_ELEMENT_ID`
LEFT JOIN `b_iblock_property` `iblock_element_apartment_property` ON `iblock_element_apartment_element_property`.`IBLOCK_PROPERTY_ID` = `iblock_element_apartment_property`.`ID`
LEFT JOIN `b_iblock_element` `iblock_element_layout` ON `iblock_element_apartment_element_property`.`VALUE` = `iblock_element_layout`.`ID`
LEFT JOIN `b_iblock_element_property` `iblock_element_layout_element_property` ON `iblock_element_layout`.`ID` = `iblock_element_layout_element_property`.`IBLOCK_ELEMENT_ID`
LEFT JOIN `b_iblock_property` `iblock_element_layout_property` ON `iblock_element_layout_element_property`.`IBLOCK_PROPERTY_ID` = `iblock_element_layout_property`.`ID`
LEFT JOIN `b_iblock` `iblock_element_iblock` ON `iblock_element`.`IBLOCK_ID` = `iblock_element_iblock`.`ID`
WHERE `iblock_element_iblock`.`CODE` = 'apartments' AND `iblock_element`.`ACTIVE` = 'Y' AND `iblock_element_apartment_property`.`CODE` = 'LAYOUTS_ID' AND `iblock_element_layout_property`.`CODE` = 'COMPLEX_ID'
GROUP BY `iblock_element_layout_element_property`.`VALUE`


https://pastebin.com/Z91qLDQb
  • Вопрос задан
  • 492 просмотра
Решения вопроса 1
@Snatch87
Битриксоид по принуждению
Если я все правильно понял, то Вам нужно немного дорабоать один из рантаймов
Приведу пример из своего кода, попробуйте адаптировать под свой:
->registerRuntimeField('PRICE', [
                'data_type' => \Bitrix\Catalog\PriceTable::class,
                'reference' => [
                    '=this.ID' => 'ref.PRODUCT_ID',
                    '=ref.CATALOG_GROUP_ID' => new \Bitrix\Main\DB\SqlExpression('?', 1)
                ]
            ])
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы