Есть основная сущность, находится, допустим, в таблице a Вот fiddle: https://www.db-fiddle.com/f/jrdevaM3SdDQfKgLF7PTph/1 У меня задача простая - выводить в гриде вот эти сущности a, но постоянно требуют еще хитрые колонки, в основном агрегирующие(сумма, первое/последнее, большее,...). И сортировать по ним. Вот, в примере сущности a.id=1 в таблице b соответствуют две записи. Так само и по таблице c. Соответственно, чтобы вывести все a с их кол-вами в других таблицах, потребовался такой запрос: Код (Text): select a.id,balias.bcount,calias.ccount from a left join (select b.a_id as baid, COUNT(b.id) as bcount from b group by baid) balias on a.id=balias.baid left join (select c.a_id as caid, COUNT(c.id) as ccount from c group by caid) calias on a.id=calias.caid Это же основной метод работы в таком случае? Выбираем основную таблицу, а к ней уже по первичным ключам, приджойниваем любые выборки, какие хочется(и неважно сколько колонок затребуют). Или какие еще варианты? Спрашиваю, т.к. мы сейчас в основном с queryBuilder-ами работаем, а там такой запрос сооружать посложнее, при этом фреймы путают своими joinWith, что просто leftJoin, и т.д. и люди пробуют через такой , в результате, запрос: Код (Text): select a.id,count(b.id) as bcount, count(c.id) as ccount from a left join b on a.id=b.a_id left join c on a.id=c.a_id group by a.id ,который дает неверный результат, как только соединение не 1:1
Какие бы вы у меня выделили представления? Те, что у меня сейчас подзапросами? Но, вообще, с представлениями не хочется иметь дела, фреймворк как yii2 их не поддерживает, видимо не может гарантировать работоспособность такого функционала в зависимости от разновидности БД
А вы ему не говорите, что это представление, а не таблица. Например объединения того, что у вас называется balias и сalias
Вся схема должна миграциями создаваться, раз нет под это команд, то не очень хорошо будет использовать. Про то что сократить тело запроса через вьюхи, понятно, но суть моего решения это ж не меняет
Одну и ту же задачу можно решать многими способами и они в разных условиях будут по-разному эффективны. Например, можно агрегировать прямо во фразе SELECT без джойнов, тыц (я здесь исходные данные немного изменил чтобы результат распределялся нагляднее, к.м.к.) Код (SQL): SELECT a.id, (SELECT COUNT(*) FROM b WHERE a_id=a.id) AS bcount, (SELECT COUNT(*) FROM c WHERE a_id=a.id) AS ccount FROM a
или может быть так покажется более выразительно: тыц Код (SQL): SELECT a.id AS a_id, COUNT(DISTINCT b.id) AS bcount, COUNT(DISTINCT c.id) AS ccount FROM a LEFT JOIN b ON b.a_id=a.id LEFT JOIN c ON c.a_id=a.id GROUP BY a.id
Первый - это кореллированный подзапрос, для каждой строки будет выполняться, рабочий вариант, но по умолчанию стараюсь избегать Второй - это способ заставить работать вариант с groupBy, хороший момент с count(distinct), проверил что и sum работает, надо подумать на теми задачами, которые обычно ко мне прилетают, везде ли такое поможет
Хотя sum( distinct) нормально тут отработает только по уникальному ключу, как первичный там, а как что то другое, то уже опять не то: , например нужно для a сумму из c.paymentsum присоединять: https://www.db-fiddle.com/f/jrdevaM3SdDQfKgLF7PTph/2
Вообще-то оптимизатор запросов MySQL довольно умён, не надо думать, что это аналог запросов в цикле ))) Часто именно такой вид работает быстрее всего. Короче, пробуй. Чем больше "активный словарь" разрабочика, тем лучше.