自动完成WHEN子句的总和

时间:2018-10-16 13:50:57

标签: sql postgresql pivot crosstab

我有一张类似的桌子

munic | origin  | date       | hour     | presence 
9875  | Germany | 2016-10-08 | 15:00:00 | 56
9875  | French  | 2016-10-08 | 18:00:00 | 24
9875  | Italians| 2016-10-08 | 18:00:00 | 6

有了SUM,我可以根据以下条件求和:

SELECT munic, 
       SUM(presence) FILTER (WHERE origin = 'Germany' AND date = '2016-10-08' AND hour = '15:00:00') AS "Germany_2016-10-08_15:00:00"

问题在于我必须对 presence 列中的值求和,但是基于太多条件,基于以下3个字段(8天x 8小时块x 12国家= 768个组合) ,太多的过滤子句无法由键盘编写。这个想法是为新闻表中三个字段的每个组合获取一个特定的总和。 除了编写每个过滤器子句,还有一种方法可以根据一般规则自动选择组合?

然后第二个问题是在新表中,如何使用类似于用于求和的三个字段的值的串联的方式来命名每个新列。

结果可以是:

   munic | Germany_2016-10-08_15:00:00 | French_2016-10-08_18:00:00 | Italians_2016-10-08_18:00:00
 9875    |    54                      |      24           |       6 

1 个答案:

答案 0 :(得分:0)

首先,我将使用行而不是列对所有这些数据进行汇总和命名。您可以包含一个(可选)where子句以获取

 SELECT munic, origin, date, hour, sum(presence) 
  from my_tab
  /*OPTIONAL where clause to limit to specific countries, origins, dates, hours*/
  WHERE origin in ('Germany','Italy','France',....)
   and date in ('2016-10-08','2016-10-09',...)
  group by munic, origin, date, hour

使用如上所述的查询,您将以行(而非列)形式获取所需的数据。此外,您将不会获得不存在数据的“空白”行。示例:如果“德国”在2016-10-08 18:00:00没有行,那么它将根本不存在。如果需要这些数据,则必须想出一种生成空白行的方法。一种方法是让表,视图或子查询仅返回每个国家/地区的名称。然后让另一个,每个时间段返回,另一个返回每个日期。然后,您将OUTER JOIN到每个表中,这将有助于生成“空白行”。

此外,不用说您的日期,时间或国家/地区列表将来可能需要更改(例如:您现在正在运行“ 2016-10-08”,但您可能需要其他日期),下一次您运行此查询时,因此另一个需要关注的问题是,每次以不同的方式运行“报告”时,如何使此查询不需要进行大量修改。

大部分问题将由您决定,什么才是最有意义的(我们是要限制数据,还是只是获取ALL ..是根据“开始日期” + X年查询的日期,等等。。。)根据您提供的信息,很难说这有什么帮助。

完成“以行格式获取数据”的初始过程之后,现在您将必须执行“数据透视”才能将行切换为列...如前所述,这不是SQL本机地或容易地做。最简单的解决方案是使用NON-SQL解决方案,使用应用程序代码将数据重新格式化为数组,对象或其他形式。当然,也可以使用pl / PGSQL或另一种DB语言来完成此操作,或者可以(很费力)在SQL中进行改革以返回所需格式的JSON数据。当然,您的应用仍将需要正确解释JSON,从逻辑上得出这样的结论:如果您可以编写应用代码,则应做最简单的事情。...最简单的解决方案是对“ Group / SUM”进行SQL中的数据,然后循环遍历并在应用程序代码中构建最终数据集。