#sql #postgresql #max #cross-join
#sql #postgresql #max #перекрестное соединение
Вопрос:
Я хочу выбрать значение max() столбца modified_at в каждой из нескольких таблиц:
select
max(a.modified_at) as a_modified_at,
max(b.modified_at) as b_modified_at,
max(c.modified_at) as c_modified_at
from a, b, c;
Это работает правильно, если в каждой из таблиц есть хотя бы 1 строка.
Проблема в том, что когда только одна из таблиц содержит 0 строк, для всех таблиц возвращается значение null:
null,null,null
Какое решение возвращает правильные значения для таблиц, в которых есть строки?
PostgreSQL-10
Ответ №1:
Использование OUTER JOIN
s должно сделать это
select
max(a.modified_at) as a_modified_at,
max(b.modified_at) as b_modified_at,
max(c.modified_at) as c_modified_at
from a outer join b outer join c;
но, возможно, более простым вариантом было бы использовать вместо этого 3 подзапроса:
select
(select max(modified_at) from a) as a_modified_at,
(select max(modified_at) from b) as b_modified_at,
(select max(modified_at) from c) as c_modified_at;
Комментарии:
1. Мне больше нравится решение с подзапросами. Это более эффективно, поскольку оно не умножает строки перед агрегацией, как это делают как попытка OP, так и
outer join
решение.2. @GMB Я бы ожидал, что Postgres будет достаточно умен, чтобы оптимизировать декартово произведение, зная, что на агрегатную функцию не влияют повторяющиеся значения. Но я доверяю вашим инстинктам больше, чем моим 🙂
3. Второе решение должно быть основным. Здесь нет никакой связи между a / b / c, которые требуются здесь