Postgres Синтаксическая ошибка в или около "FILTER" - PullRequest
0 голосов
/ 30 января 2020

Я использую PostgreSQL версию 12.1 на своей локальной машине и написал запрос

SELECT cit.id, cit.city, cit.google_sheet_links,
COALESCE(json_agg(
  json_build_object(
      'id', c_sch.id, 
      'name', c_sch.name,
      'animation', c_sch.animation,
      'headerBgColor', c_sch.header_color_bg,
      'headerTextColor', c_sch.header_color_text,
      'headerText', c_sch.header_text,
      'bodyBgColor', c_sch.body_color_bg,
      'bodyCurrencyColor', c_sch.body_color_currency,
      'bodyNumbersColor', c_sch.body_color_numbers,
      'bodyHeadersColor', c_sch.body_color_headers,
      'footerBgColor', c_sch.footer_color_bg,
      'footerColor', c_sch.footer_color_text,
      'footerText', c_sch.footer_text
    )
  )
FILTER (WHERE c_sch.id IS NOT NULL), '[]') AS screens
FROM public.cities cit LEFT JOIN public.color_schemes c_sch
ON c_sch.city_id = cit.id
GROUP BY cit.id;

, но сервер использует postgresql версию 9.2.24, и когда я хочу использовать текущий запрос, я получаю ошибку.

error: syntax error at or near "FILTER"

Как это исправить?

Ответы [ 2 ]

3 голосов
/ 30 января 2020

Расширение filter для агрегатных функций было добавлено в Postgres 9.4 (выпущено в 2014 г.).

В более ранних версиях вы можете использовать условное выражение внутри агрегатной функции, например:

json_agg(
    case when c_sch.id is not null
        then json_build_object(
            'id', c_sch.id, 
            'name', c_sch.name,
            'animation', c_sch.animation,
            'headerBgColor', c_sch.header_color_bg,
            'headerTextColor', c_sch.header_color_text,
            'headerText', c_sch.header_text,
            'bodyBgColor', c_sch.body_color_bg,
            'bodyCurrencyColor', c_sch.body_color_currency,
            'bodyNumbersColor', c_sch.body_color_numbers,
            'bodyHeadersColor', c_sch.body_color_headers,
            'footerBgColor', c_sch.footer_color_bg,
            'footerColor', c_sch.footer_color_text,
            'footerText', c_sch.footer_text
        )
    end
)

Однако обратите внимание, что, как прокомментировал Ник Барнс, json_agg() не игнорирует null с (в отличие от других стандартных агрегатных функций, таких как min(), max() и т. Д.), поэтому вышеприведенный запрос не даст тот же результат, что и при использовании предложения filter.

Одним из решений было бы перенести агрегацию в подзапрос:

select
    cit.id, 
    cit.city, 
    cit.google_sheet_links,
    (
        select coalesce(
            json_agg(
                json_build_object(
                    'id', c_sch.id, 
                    'name', c_sch.name,
                    'animation', c_sch.animation,
                    'headerBgColor', c_sch.header_color_bg,
                    'headerTextColor', c_sch.header_color_text,
                    'headerText', c_sch.header_text,
                    'bodyBgColor', c_sch.body_color_bg,
                    'bodyCurrencyColor', c_sch.body_color_currency,
                    'bodyNumbersColor', c_sch.body_color_numbers,
                    'bodyHeadersColor', c_sch.body_color_headers,
                    'footerBgColor', c_sch.footer_color_bg,
                    'footerColor', c_sch.footer_color_text,
                    'footerText', c_sch.footer_text
                )
            ),
            '[]'
        )
        from public.color_schemes c_sch
        where c_sch.id is not null and c_sch.city_id = cit.id
    ) screens
from public.cities cit;
0 голосов
/ 30 января 2020

кажется, что вы пропустили a) до FILTER

SELECT cit.id, cit.city, cit.google_sheet_links,
COALESCE(json_agg(
  json_build_object(
      'id', c_sch.id, 
      'name', c_sch.name,
      'animation', c_sch.animation,
      'headerBgColor', c_sch.header_color_bg,
      'headerTextColor', c_sch.header_color_text,
      'headerText', c_sch.header_text,
      'bodyBgColor', c_sch.body_color_bg,
      'bodyCurrencyColor', c_sch.body_color_currency,
      'bodyNumbersColor', c_sch.body_color_numbers,
      'bodyHeadersColor', c_sch.body_color_headers,
      'footerBgColor', c_sch.footer_color_bg,
      'footerColor', c_sch.footer_color_text,
      'footerText', c_sch.footer_text
    )
  )
)
FILTER (WHERE c_sch.id IS NOT NULL), '[]') AS screens
FROM public.cities cit LEFT JOIN public.color_schemes c_sch
ON c_sch.city_id = cit.id
GROUP BY cit.id;

или вам нужно какое-то значение для объединения, а затем a) до FILTER

...