Я считаю, что это больше вопрос SQL. Использование построителя запросов к БД:
DB::select('songs.*')->select(array('COUNT("keywords.id")', 'nconnections'))
->from('songs')
->join('connections', 'LEFT')->on('connections.song_id', '=', 'songs.id')
->join('keywords', 'LEFT')->on('connections.keyword_id', '=', 'keywords.id')
->group_by('songs.id')
->order_by('nconnections')
->as_object('Model_Song')
->execute();
или в SQL
SELECT `songs`.*, COUNT(`keywords`.`id`) AS `nconnections` FROM songs
LEFT JOIN `connections` ON `connections`.`song_id` = `songs`.`id`
LEFT JOIN `keywords` ON `connections`.`keyword_id` = `keywords`.`id`
GROUP BY `songs`.`id` ORDER BY `nconnections`
должен вернуть желаемый результат.
Вам понадобится доступное свойство под названием nconnections
в вашей модели песни. Самый простой способ сделать это - добавить публичного участника, чтобы не вмешиваться во внутреннюю работу ORM.
Я предполагаю, что вы используете модель под названием «Song», связанную с таблицей «песен», модель «Ключевого слова», связанную с таблицей «ключевых слов» и в внешних ключах таблицы «соединений» «song_id» и 'keyword_id' для каждой модели соответственно.