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
синтаксис.