За последние 24 часа нас посетили 10356 программистов и 673 робота. Сейчас ищут 272 программиста ...

А как кто присоединяет дополнительные(сложные) столбцы к основной таблице?

Тема в разделе "MySQL", создана пользователем Дюран, 13 янв 2022.

  1. Дюран

    Дюран Активный пользователь

    С нами с:
    9 мар 2018
    Сообщения:
    202
    Симпатии:
    9
    Есть основная сущность, находится, допустим, в таблице a
    Вот fiddle:
    https://www.db-fiddle.com/f/jrdevaM3SdDQfKgLF7PTph/1

    У меня задача простая - выводить в гриде вот эти сущности a, но постоянно требуют еще хитрые колонки, в основном агрегирующие(сумма, первое/последнее, большее,...). И сортировать по ним.
    Вот, в примере сущности a.id=1 в таблице b соответствуют две записи.
    Так само и по таблице c.
    Соответственно, чтобы вывести все a с их кол-вами в других таблицах, потребовался такой запрос:
    Код (Text):
    1. select a.id,balias.bcount,calias.ccount
    2. from a
    3. left join (select b.a_id as baid, COUNT(b.id) as bcount from b group by baid) balias on a.id=balias.baid
    4. 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):
    1. select a.id,count(b.id) as bcount, count(c.id) as ccount
    2. from a
    3. left join b on a.id=b.a_id
    4. left join c on a.id=c.a_id
    5. group by a.id
    ,который дает неверный результат, как только соединение не 1:1
     
  2. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.130
    Симпатии:
    226
    Нет.
    Создайте из сложных запросов необходимые представления.
    И объединяйте их как таблицы.
     
  3. Дюран

    Дюран Активный пользователь

    С нами с:
    9 мар 2018
    Сообщения:
    202
    Симпатии:
    9
    Какие бы вы у меня выделили представления?
    Те, что у меня сейчас подзапросами?

    Но, вообще, с представлениями не хочется иметь дела, фреймворк как yii2 их не поддерживает, видимо не может гарантировать работоспособность такого функционала в зависимости от разновидности БД
     
  4. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.130
    Симпатии:
    226
    А вы ему не говорите, что это представление, а не таблица.
    Например объединения того, что у вас называется balias и сalias
     
  5. Дюран

    Дюран Активный пользователь

    С нами с:
    9 мар 2018
    Сообщения:
    202
    Симпатии:
    9
    Вся схема должна миграциями создаваться, раз нет под это команд, то не очень хорошо будет использовать.

    Про то что сократить тело запроса через вьюхи, понятно, но суть моего решения это ж не меняет
     
  6. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    10.658
    Симпатии:
    1.124
    Адрес:
    там-сям
    Одну и ту же задачу можно решать многими способами и они в разных условиях будут по-разному эффективны.

    Например, можно агрегировать прямо во фразе SELECT без джойнов, тыц
    (я здесь исходные данные немного изменил чтобы результат распределялся нагляднее, к.м.к.)
    Код (SQL):
    1. SELECT
    2.   a.id,
    3.   (SELECT COUNT(*) FROM b WHERE a_id=a.id) AS bcount,
    4.   (SELECT COUNT(*) FROM c WHERE a_id=a.id) AS ccount
    5. FROM a
     
    Дюран нравится это.
  7. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    10.658
    Симпатии:
    1.124
    Адрес:
    там-сям
    или может быть так покажется более выразительно: тыц

    Код (SQL):
    1. SELECT
    2.   a.id AS a_id,
    3.   COUNT(DISTINCT b.id) AS bcount,
    4.   COUNT(DISTINCT c.id) AS ccount
    5. FROM a
    6. LEFT JOIN b ON b.a_id=a.id
    7. LEFT JOIN c ON c.a_id=a.id
    8. GROUP BY a.id
     
    Дюран нравится это.
  8. Дюран

    Дюран Активный пользователь

    С нами с:
    9 мар 2018
    Сообщения:
    202
    Симпатии:
    9
    Первый - это кореллированный подзапрос, для каждой строки будет выполняться, рабочий вариант, но по умолчанию стараюсь избегать

    Второй - это способ заставить работать вариант с groupBy, хороший момент с count(distinct), проверил что и sum работает, надо подумать на теми задачами, которые обычно ко мне прилетают, везде ли такое поможет
     
  9. Дюран

    Дюран Активный пользователь

    С нами с:
    9 мар 2018
    Сообщения:
    202
    Симпатии:
    9
    Хотя sum( distinct) нормально тут отработает только по уникальному ключу, как первичный там, а как что то другое, то уже опять не то:
    , например нужно для a сумму из c.paymentsum присоединять:
    https://www.db-fiddle.com/f/jrdevaM3SdDQfKgLF7PTph/2
     
  10. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    10.658
    Симпатии:
    1.124
    Адрес:
    там-сям
    Вообще-то оптимизатор запросов MySQL довольно умён, не надо думать, что это аналог запросов в цикле ))) Часто именно такой вид работает быстрее всего. Короче, пробуй. Чем больше "активный словарь" разрабочика, тем лучше.