构建SQL查询,汇总不同类别和不同条件的总值

时间:2017-06-26 11:07:51

标签: sql subquery postgresql-9.6

我正在使用PostgreSQL 9.6,我正在尝试在一个表上创建一个查询,该查询可以汇总不同站点中类别的总区域。 下面是我的表的简化版本。

Id  |  category (text)  |  area (real)  |  site (text)
 1  |   short grass 1   |      10       |     park 1
 2  |   short grass 2   |      15       |     park 2
 3  |   long grass 1    |      25       |     park 1
 4  |   long grass 2    |      18       |     park 3
 5  |   short grass 1   |      7        |     roadside 1
 6  |   short grass 2   |      4        |     roadside 2
 7  |   long grass 1    |      14       |     roadside 1
 8  |   long grass 2    |      7        |     roadside 3
  • Id是标准主键设置
  • 类别识别不同长度的草(例如减少)
  • 面积是草地区域的小数位数
  • 网站是草地的位置

我瞄准的完成的表是按草类别(第2列)和网站(第4列)分类的总面积:

    site (text)        |  short grass   |  long grass
                          total area       total area
  park (grouped)       |      25        |      43
 roadside (grouped)    |      11        |      21

我认为我在SUM函数中使用CASE WHEN语句取得了一些成功,但是不是根据不同的条件创建具有面积总数的多行,而是将它们一起添加到单个SUM中,事后我意识到这是什么我问它要做。 (以下代码的简短示例):

SELECT SUM(CASE WHEN category LIKE 'short grass%' AND site LIKE 'park%' THEN area
    WHEN category LIKE 'long grass%' AND site LIKE 'park%' THEN area END) 
from my_table;

我期待的是两行具有不同的区域总数。到目前为止,我已经使用了我的代码,我认为我甚至没有朝着正确的方向前进。

我考虑过嵌套的SELECT查询和连接,但我的SQL知识不是很好,所以我不知道从哪里开始编写它。

2 个答案:

答案 0 :(得分:1)

我认为这就是你要做的事。

SELECT case when site like 'park%' then 'park' 
            when site like 'roadside%' then 'roadside' 
       --add else if required
       end as site,
SUM(CASE WHEN category LIKE 'short grass%' THEN area ELSE 0 END) as short_grass
SUM(CASE WHEN category LIKE 'long grass%' THEN area ELSE 0 END) as long_grass
from my_table
group by case when site like 'park%' then 'park' 
              when site like 'roadside%' then 'roadside' 
         --add else if required
         end

答案 1 :(得分:0)

您如何定义群组?如果您只想要site中的第一个单词,那么:

select substring(site from '#"%#" %' for '#') as sitetype,
       sum(case when category like 'short grass%' then area else 0 end) as shortgrass,
       sum(case when category like 'long grass%' then area else 0 end) as longgrass
from my_table
group by sitetype;