【问题标题】:Sql query like pivot table from vertical list in postgresql effectively有效地从 postgresql 中的垂直列表进行 Sql 查询,如数据透视表
【发布时间】:2020-07-03 19:53:42
【问题描述】:

我想从垂直列表中编写一个像数据透视表这样的 sql 查询。让我们看一个例子:

我的表格数据:

表 1 -> 元数据:

id text  
1  t1
2  t2
3  t3

表 2 -> 报告:

date          category      revenue  metadata_id
2020-01-01    TRIAL           1          1
2020-01-01    PURCHASE       1.2         2
2020-01-03    SUBSCRIPTION   1.4         3
2020-01-03    PURCHASE       1.1         3

...

在这里,我想创建一个 sql 查询以从特定范围和 ids 过滤器中获取结果,例如:

Request:
start-date: 2020-01-01
end-date: 2020-01-30
ids: 1,2....100

预期结果:

id       text       category_trial      category_purchase   category_SUBSCRIPTION
1         t1             1                      0                     0
2         t2             0                      1.2                   0
3         t3             0                      1.1                  1.4

在这里,我写了一个如下的sql:

select
m.id,
m.text,
t1.rev as category_trial,
t2.rev as category_purchase,
t3.rev as category_SUBSCRIPTION
from metadata m
left join 
(
  select 
metadata_id,
sum(revenue) as rev
from report where category = 'TRIAL' and report_date between '2020-01-01' and '2020-01-30'
group by  metadata_id
) t1 on t1.metadata_id = m.id 
left join 
(
  select 
metadata_id,
sum(revenue) as rev
from report where category = 'PURCHASE' and report_date between '2020-01-01' and '2020-01-30'
group by  metadata_id
) t2 on t2.metadata_id = m.id 
left join 
(
  select 
metadata_id,
sum(revenue) as rev
from report where category = 'SUBSCRIPTION' and report_date between '2020-01-01' and '2020-01-30'
group by  metadata_id
) t3 on t3.metadata_id = m.id 
...

在这里我有超过 7 个类别。

我的问题在这里,这个 sql 工作但性能不够。有什么建议可以提高它的性能吗?

注意:我是在 postgresql 中编写的,并且使用了索引。

【问题讨论】:

    标签: sql postgresql performance


    【解决方案1】:

    我不经常使用 Postgres,但是这个查询应该更快:

    select id, text,
           sum(case category when 'TRIAL'        then revenue else 0 end) cat_tri,
           sum(case category when 'PURCHASE'     then revenue else 0 end) cat_pur,
           sum(case category when 'SUBSCRIPTION' then revenue else 0 end) cat_sub   
      from (
        select id, text, category, revenue 
          from metadata m join report r on m.id = r.metadata_id
          where date_ between '2020-01-01' and '2020-01-30' 
            and id between 1 and 100 ) t   
      group by id, text 
      order by id
    

    dbfiddle

    结果如预期,只有一个join、过滤和分组。

    【讨论】:

    • 实际上,您甚至不需要subquery。此外,请务必使用表或别名来限定 JOIN 查询中的 every 字段,无论它是否为 Postgres。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 2019-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    相关资源
    最近更新 更多