生成连接多个表并汇总某些列的PostgreSQL查询

时间:2018-08-17 22:39:10

标签: ruby-on-rails postgresql

我正在尝试通过PostgreSQL查询返回下表:

container length | terminal 1 | terminal 2 | terminal 3 | Cumulative
----------------------------------------------------------------------
10               |   12       |     12     |     12     |     36     |
20               |   34       |     34     |     34     |     102    |
30               |   56       |     56     |     56     |     168    |
40               |   78       |     78     |     78     |     234    |

数字组成了,但是本质上我希望能够看到:

  • 第一列中的容器长度
  • 我所有的码头,每个集装箱长度都有各自的集装箱数量
  • 第4列中每一行的这些值的总和(第2-4列)。

是否可以通过SQL查询?

这些表格如下:

Organization
 - terminal_id
 - container_id

Container
 - organization_id
 - current_location_type
 - current_location_id

Terminal
 - organization_id

换句话说,一个组织有很多容器并且有很多终端。终端属于组织。容器属于组织。

我可以从容器派生终端的方式是:containers.current_location_type = 'Terminal'containers.current_location_id = terminals.id

我有以下SQL查询,但它没有以我希望在上表中返回数据的方式返回数据。

SELECT containers.container_length AS container_length,
  terminals.name AS terminal_name,
  COUNT(*) AS group_count
FROM containers
LEFT JOIN terminals
  ON terminals.organization_id = organization.id
  AND terminals.id = containers.current_location_id
WHERE containers.organization_id = organization.id
  AND containers.current_location_type = 'Terminal'
GROUP BY containers.container_length, terminals.id
ORDER BY container_length ASC

此查询返回3列:container_lengthterminal_namegroup_count。好像我走在正确的道路上,但是我无法像上表那样找到一种方法来获得它。关于如何实现此目标有任何想法吗? 谢谢!

1 个答案:

答案 0 :(得分:1)

自9.4起,postgres便可以使用FILTER子句选择性地应用聚合。

您可以执行以下操作:

SELECT
  containers.container_length,
  count(*) FILTER (WHERE terminals.name = 'terminal_1') AS terminal_1,
  count(*) FILTER (WHERE terminals.name = 'terminal_2') AS terminal_2,
  count(*) FILTER (WHERE terminals.name = 'terminal_3') AS terminal_3,
  count(*) AS cumulative
FROM containers -- ...

您必须将分组调整为仅按container_length