Наконец я нашел решение:
$position = TableRegistry::getTableLocator()->get('Positions');
$q = $position->find();
$q->select([$q->func()->count('*')])
->where(['Positions.group_id = Groups.id']);
$query = $this->Groups->find()
->select(['id', 'name', 'created', 'modified' , 'count' => $q]);
При проверке журнала я получаю:
SELECT Groups.id AS `Groups__id`, Groups.name AS `Groups__name`, Groups.created AS `Groups__created`, Groups.modified AS `Groups__modified`, (SELECT (COUNT(*)) FROM positions Positions WHERE Positions.group_id = Groups.id) AS `count` FROM groups Groups