как получить первое (или любое отдельное) значение в GROUP BY без ARRAY_AGG?

Я переношу некоторый 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)...

Обратите внимание, что нам не так важно получить первое значение, нам просто нужно любое (в идеале детерминированное) одиночное значение.

Заранее спасибо.


person Matthew Cornell    schedule 28.01.2014    source источник
comment
Я немного не понимаю, чего вы пытаетесь достичь с помощью (array_agg(A.X))[1]. Без предложения order by это даст вам первое из случайно упорядоченного списка A.X. Тот факт, что вы получаете ожидаемый результат, является чистой удачей из-за того, что ваша статистика заставляет Postgres предпочесть план, который подходит…   -  person Denis de Bernardy    schedule 28.01.2014
comment
Я могу ошибаться, но почему бы вам просто не использовать SELECT B.id, min(A.X) from ... group by b.id? Я не понимаю, зачем вообще нужен array_agg().   -  person a_horse_with_no_name    schedule 29.01.2014


Ответы (1)


Комментарий @a_horse_with_no_name вместе с комментарием Дениса был тем, что нам нужно было, чтобы переосмыслить наш подход. Мы перешли на MIN(). Спасибо!

person Matthew Cornell    schedule 03.02.2014