PostgreSQL和Crosstab():错误:返回和sql元组描述不兼容

时间:2017-07-11 04:41:35

标签: sql postgresql crosstab

我正在运行以下基本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()查询:

SELECT * FROM crosstab
('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')
AS (project_name TEXT, July_2016 INTEGER, August_2016 INTEGER, September_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

但是我收到错误:

  

错误:return和sql元组描述不兼容

visitors我永远不会有任何空或遗失结果。我之前读过有关crosstab()的第二个参数的帖子,我不相信我需要它。我尝试将INTEGER中的crosstab()列更改为NUMERIC,但我仍然收到相同的错误。

我做错了什么?有人可以提供修改后的crosstab()查询来向我显示修复方法吗?

1 个答案:

答案 0 :(得分:0)

我只会使用条件聚合:

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()
  • 使用日期的标准格式 - YYYY-MM-DD。
  • FROM子句中的子查询是不必要的。
  • 从不FROM子句中使用逗号。始终使用正确的,明确的JOIN语法。