Подсчёт значений из присоединённой таблицы на xPDO

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

В итоге вышел простой и быстрый сниппет getSections:
<?php
if (empty($tpl)) {$tpl = 'tpl.Tickets.form.section.row';}
if (empty($section)) {$section = 0;}

// Новый запрос - выбираем родителей
$q = $modx->newQuery('TicketsSection', array('class_key' => 'TicketsSection', 'published' => 1, 'deleted' => 0));
// Присоединяем потомков и указываем какое поле их связывают с родителем
$q->leftJoin('Ticket','Ticket','TicketsSection.id = Ticket.parent AND Ticket.published = 1 AND Ticket.deleted = 0');
// Группируем ряды по родителям, без этого работать не будет
$q->groupby('TicketsSection.id');
// Выбираем id, имя родителя и кол-во активных потомков функцией COUNT
$q->select('TicketsSection.id, TicketsSection.pagetitle, COUNT(Ticket.id) as count');
// Сортируем по menuindex
$q->sortby('TicketsSection.menuindex', 'ASC');

// Дальше обычный разбор результатов
if ($q->prepare() && $q->stmt->execute()) {
    $res = $q->stmt->fetchAll(PDO::FETCH_ASSOC);
    $res = '';
    
    foreach ($res as $v) {
        if ($v['id'] == $section) {$v['selected'] = 'selected';} else {$v['selected'] = '';}
        $res .= $modx->getChunk($tpl, $v);
    }
    
    return $res;
}

В сниппет можно передать параметр section для указания активного раздела и tpl для оформления.

Еще нужно немного изменить чанк tpl.Tickets.form.section.row, для вывода count:
<option value="[[+id]]" [[+selected]]>[[+pagetitle]][[+count:gt=`0`:then=` ([[+count]])`:else=``]]</option>

Данный способ присоединения таблицы и подсчета её рядов будет работать везде, не только с тикетами. Можно даже посчитать сумму значений и отсортировать по ней. Вот пример из будущей системы рейтинга тикетов:
$q = $modx->newQuery('Ticket', array('class_key' => 'Ticket','deleted' => 0, 'published' => 1));
$q->leftJoin('TicketVote','Vote', "Ticket.id = Vote.parent AND Vote.class = 'Ticket'");
$q->groupby('Ticket.id');
$q->select("SUM(Vote.value) as rating");
$q->sortby('rating', 'DESC');
Василий Наумкин
10 декабря 2012, 05:22
modx.pro
7
3 600
0

Комментарии: 0

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