PostgreSQL,CASE WHEN和IF

时间:2016-01-06 20:05:41

标签: sql postgresql

我有一张桌子,上面有特定年份的一些城市,餐馆和订单(每家餐馆)。 从这个数据集中,我有一个问题,说明:

  • 在平均订单高于120的城市,应该中止少于100个订单的餐馆。
  • 在平均订单高于60的城市,应该中止少于40个订单的餐馆。
  • 在平均订单高于30的城市,应该中止少于20个订单的餐馆。

到目前为止,我已经创建了一个查询,可以为我提供一个表格,其中包含每个城市的平均订单,并将其标记为1,2,3或4,如下所示:

SELECT cities, AVG(orders), COUNT(restaurants),
      CASE 
         WHEN (AVG(orders) >= 120) THEN '1'
         WHEN (120 > AVG(orders) >= 60) THEN '2'
         WHEN (60 > AVG(orders) >= 30) THEN '3'
         ELSE '4'
         END AS ranking
FROM c_cities
GROUP BY 1

所以,现在我想创建一个将检查例如的语句: 对于评级= 1,如果订单> 100 - >保留它们或将它们标记为某种东西。 对于评级= 2,如果订单> 60 - >类似等等。

我试图在其中找到逻辑和正确的陈述。 我认为一个案例......什么时候无法解决我的问题。 我正在阅读IF语句的文档,但我无法使其工作。

如果您能提供任何帮助,我将不胜感激:)

1 个答案:

答案 0 :(得分:1)

我遵循你的要点中的逻辑,但不是问题的其余部分。要实现该逻辑,请使用窗口函数,然后使用where。例如,以下内容根据您的定义获取应该“中止”的餐馆:

select cr.*
from (select c.city, c.restaurant, avg(orders) as restaurant_avg,
             (sum(orders) over (partition by city) /
              count(distinct restaurant) over (order by city)
             ) as city_avg
      from c_cities
      group by c.city, c.restaurant
     ) cr
where (city_avg > 120 and restuarant_avg < 100) or
      (city_avg > 100 and restaurant_avg < 80) or
      (city_avg > 30 and restaurant_avg < 20);

这个想法是为每一行计算城市和餐馆的平均值。然后你可以比较它们。