Я переношу некоторый SQL из PostgreSQL 9.2 в Vertica 7.0, и мне не помешала бы помощь в замене классного array_agg с чем-то, что Vertica (и, возможно, другие СУБД) поддерживает, например, разделы и оконные функции. Я новичок в этих функциях, и я был бы очень признателен за ваши идеи.
(Рабочий) запрос с использованием array_agg ( демонстрация скрипки sql ):
SELECT B.id, (array_agg(A.X))[1]
FROM B, AB, A
WHERE B.id = AB.B_id AND A.id = AB.A_id AND A.X IS NOT NULL
GROUP BY B.id;
Если я попытаюсь наивно выбрать AX сам по себе без агрегации (т. е. позволить СУБД выбирать - на самом деле работает с MySQL и SQLite), postgres жалуется. Выполнение того же запроса, но с «A.X» вместо «(array_agg(A.X))1":
ERROR: column "a.x" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT B.id, A.X
Я думал попробовать оконную функцию, например, что-то вроде этот вопрос а>:
SELECT email, FIRST_VALUE(email) OVER (PARTITION BY email)
FROM questions
GROUP BY email;
но я получаю ту же ошибку:
SELECT B.id, FIRST_VALUE(A.X) OVER (PARTITION BY A.id)
FROM B, AB, A
WHERE B.id = AB.B_id AND A.id = AB.A_id AND A.X IS NOT NULL
GROUP BY B.id;
ERROR: column "a.x" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT B.id AS id, FIRST_VALUE(A.X) OVER (PARTITION BY A.id)...
Обратите внимание, что нам не так важно получить первое значение, нам просто нужно любое (в идеале детерминированное) одиночное значение.
Заранее спасибо.
(array_agg(A.X))[1]
. Без предложения order by это даст вам первое из случайно упорядоченного списка A.X. Тот факт, что вы получаете ожидаемый результат, является чистой удачей из-за того, что ваша статистика заставляет Postgres предпочесть план, который подходит… - person Denis de Bernardy   schedule 28.01.2014SELECT B.id, min(A.X) from ... group by b.id
? Я не понимаю, зачем вообще нуженarray_agg()
. - person a_horse_with_no_name   schedule 29.01.2014