PostgreSQL и Crosstab(): ОШИБКА: описания возвращаемых и sql кортежей несовместимы

Я бегу следующие основные SQL запрос:

SELECT
  a.project_name,
  CASE
    WHEN to_char(date_trunc('month', u.billing_period_start), 'MM-YYYY') = '07-2016' THEN 'July_2016'
    WHEN to_char(date_trunc('month', u.billing_period_start), 'MM-YYYY') = '08-2016' THEN 'August_2016'
    WHEN to_char(date_trunc('month', u.billing_period_start), 'MM-YYYY') = '09-2016' THEN 'September_2016'
  END AS billing_month,
  u.unique_visitor_count AS visitors
FROM table_1 u,
     (SELECT
       a.account_id AS project_id,
       a.project_name
     FROM table_2 a) a
WHERE u.project_id = a.project_id
AND date_trunc('month', u.billing_period_start) BETWEEN '2016-07-01' AND '2016-09-01'
ORDER BY 1, 2;

Этот запрос возвращает мне следующий набор результатов: project_name | month_name | visitors -------------|----------------|--------- name_1 | August_2016 | 0 name_1 | July_2016 | 0 name_1 | September_2016 | 0 name_2 | August_2016 | 0 name_2 | July_2016 | 0 name_2 | September_2016 | 0 name_3 | August_2016 | 39 name_3 | July_2016 | 68 name_3 | September_2016 | 25 name_4 | August_2016 | 536914 name_4 | July_2016 | 16142 name_4 | September_2016 | 487117

Я пытаюсь использовать следующее crosstab() запрос:

ВЫБРАТЬ * ИЗ Кросс-таблицы
('ВЫБРАТЬ 
    a.project_name,
    случай, когда to_char(date_trunc(''month'', u.billing_period_start),''MM-YYYY'')=''07-2016'' then ''July_2016''
         когда to_char(date_trunc(''month'', u.billing_period_start),''MM-YYYY'')=''08-2016'' тогда ''August_2016''
         когда to_char(date_trunc(''month'', u.billing_period_start),''MM-YYYY'')=''09-2016'' тогда '' сентябрь_2016 '' заканчивается как billing_month,
    u.unique_visitor_count в качестве посетителей
FROM table_1 u,
     (выберите a.account_id как project_id, a.project_name
      из таблицы_2 а) а
где u.project_id = a.project_id
и date_trunc ('' month '', u.billing_period_start) между ''2016-07-01'' и ''2016-09-01''
заказать на 1,2')
AS (имя_проекта TEXT, июль_2016, INTEGER, август_2016, INTEGER, сентябрь_2016, INTEGER);

Я хочу превратить первый набор результатов выше в следующее: project_name | July_2016 | August_2016 | September_2016 ------------|-----------|-------------|--------------- name_1 | 0 | 0 | 0 name_2 | 0 | 0 | 0 name_3 | 68 | 39 | 25 name_4 | 16142 | 536914 | 487117

Однако я получаю сообщение об ошибке:

ОШИБКА: описания возвращаемых и sql-кортежей несовместимы

У меня никогда не будет нулевых или пропущенных результатов для visitors, Я читал предыдущие посты о втором параметре для crosstab() и я не верю, что мне это нужно здесь. Я пытался изменить INTEGER колонны в моем crosstab() в NUMERIC, но я все еще получаю ту же ошибку.

Что я делаю неправильно? Может ли кто-нибудь предоставить модифицированный, работающий crosstab() запрос, чтобы показать мне исправление?

1 ответ

Я бы просто использовал условную агрегацию:

SELECT a.project_name,
       SUM(case when date_trunc('month', u.billing_period_start) = '2016-07-01'
                then u.unique_visitor_count else 0
           end) as uv_201607,
       SUM(case when date_trunc('month', u.billing_period_start) = '2016-08-01' 
                then u.unique_visitor_count else 0
           end) as uv_201608,
       SUM(case when date_trunc('month', u.billing_period_start) = '2016-09-01' 
                then u.unique_visitor_count else 0
           end) as uv_201609
FROM table_1 u JOIN
     table_2 a
     ON u.project_id = a.project_id
WHERE  date_trunc('month', u.billing_period_start) BETWEEN '2016-07-01' AND '2016-09-01'
GROUP BY a.project_name
ORDER BY a.project_name;

Заметки:

  • Там нет необходимости использовать to_char() на date_trunc(),
  • Используйте стандартные форматы для дат - ГГГГ-ММ-ДД.
  • Подзапрос в FROM пункт не нужен.
  • Никогда не используйте запятые в FROM пункт. Всегда используйте правильный, явный JOIN синтаксис.
Другие вопросы по тегам