Как получить идентификаторы сгруппированных по строкам в postgresql и использовать результат?

У меня есть таблица, содержащая транзакции с суммой. Я хочу создать пакет транзакций, чтобы сумма суммы каждой «группы» была отрицательной.
Моя проблема заключается в том, чтобы получить все идентификаторы строк, связанных с «группой», где каждая группа проверяется условием суммы.

Я нахожу много решений, которые не работают для меня. Лучшее решение, которое я нашел, - это запросить базу данных в первый раз с «группой по» и суммой, а затем вернуть идентификаторы, чтобы, наконец, запросить базу данных еще раз со всеми из них.

Вот пример того, что я хотел бы (это не работает!):

SELECT * FROM transaction_table transaction 
AND transaction.id IN (
    select string_agg(grouped::character varying, ',' ) from (
        SELECT array_agg(transaction2.id) as grouped FROM transaction_table transaction2 
        WHERE transaction2.c_scte='c'
        AND (same conditions)
        GROUP BY
            transaction2.motto ,
            transaction2.accountBnf ,
            transaction2.payment ,
            transaction2.accountClt 
        HAVING sum(transaction2.amount)<0
    )
);

результат array_agg выглядит так:

{39758,39759}
{39757,39756,39755,39743,39727,39713}

и string_agg:

{39758,39759},{39757,39756,39755,39743,39727,39713}

Теперь мне просто нужно их использовать, но я не знаю, как...

к сожалению, это не работает из-за приведения типов:

ERROR: operator does not exist: integer = integer[]
  Indice : No operator matches the given name and argument type(s). You might need to add explicit type casts.

person Pierre Taquet    schedule 11.10.2019    source источник


Ответы (2)


Может быть, вы ищете

SELECT id, motto, accountbnf, payment, accountclnt, amount
FROM (SELECT id, motto, accountbnf, payment, accountclnt, amount,
             sum(amount)
                OVER (PARTITION BY motto, accountbnf, payment, accountclnt)
                AS group_total
      FROM transaction_table) AS q
WHERE group_total < 0;

Внутренний SELECT добавляет дополнительный столбец, используя оконную функцию, которая вычисляет сумму для каждой группы, а внешний запрос удаляет все результаты, где эта сумма не является отрицательной.

person Laurenz Albe    schedule 11.10.2019
comment
У меня это не работает, компилятор сообщает об ошибке рядом с ')'. Я нашел решение, которое я только что опубликовал - person Pierre Taquet; 11.10.2019
comment
Действительно, не хватает запятой @Laurenz [...] accountclnt, amount !,! sum(amount) [...] - person Islingre; 11.10.2019

Наконец, я нашел этот вариант, используя метод «unnest». Это работает отлично.

  • Array_agg объединяет все идентификаторы в разные массивы
  • негнездо сплющило их всех

Это взято из здесь

SELECT * FROM transaction_table transaction 
WHERE transaction.id = ANY(
    SELECT unnest(array_agg(transaction2.id)) as grouped FROM transaction_table transaction2 
    WHERE transaction2.c_scte='c'
    AND (same conditions)
    GROUP BY
        transaction2.motto ,
        transaction2.accountBnf ,
        transaction2.payment ,
        transaction2.accountClt 
    HAVING sum(transaction2.amount)<0
);

Проблема с этим решением заключается в том, что hibernate не учитывает метод array_agg.

person Pierre Taquet    schedule 11.10.2019
comment
@a_horse_with_no_name Я только что попробовал выполнить запрос без раскладки, и он выдал эту ошибку: ОШИБКА: оператор не существует: целое = целое [] Индекс: ни один оператор не соответствует заданному имени и типу (ам) аргумента. Возможно, вам потребуется добавить явное приведение типов. Я пытался бросить его, но я получаю тот же результат. метод unnest кажется важным в моем случае. Возможно, из-за моей базы данных postgreSQL... - person Pierre Taquet; 14.10.2019
comment
@a_horse_with_no_name Определенно нет, я не удалял any!! Я только что удалил unnset(). Пожалуйста, попробуйте со своей стороны, = any(select array_agg(....) ...) просто не работает без unnest(), когда возвращаются 2 или более строк, и это довольно логично. - person Pierre Taquet; 15.10.2019