SQL:JOIN然后注释,而不是JOIN然后分组?

时间:2015-07-03 10:55:22

标签: sql postgresql

我在Postgres 9.4工作。我有两个表,一个用于组织,主键字段为code

          Table "public.org"
    Column     |          Type          | Modifiers
---------------+------------------------+-----------
 code          | character varying(6)   | not null
 name          | character varying(200) | not null
 postcode      | character varying(9)   |
Indexes:
  "org_pkey" PRIMARY KEY, btree (code)

一个按组织和月份支出项目,外键返回组织表:

 Table "public.spending_item"
      Column       |          Type           |                             Modifiers
-------------------+-------------------------+--------------------------------------------------------------------
 id                | integer                 | not null default nextval('frontend_prescription_id_seq'::regclass)
 actual_cost       | double precision        | not null
 quantity          | double precision        | not null
 processing_date   | date                    | not null
 org_id            | character varying(6)    | not null
Foreign-key constraints:
  "fk_1234" FOREIGN KEY (org_id) REFERENCES org(code) DEFERRABLE INITIALLY DEFERRED

我希望按月找到按组织划分的总支出,以及组织名称和邮政编码。

这是我目前的查询:

SELECT pr.org_id as org_id, 
       pc.name as org_name, 
       pc.postcode as org_postcode, 
       SUM(pr.actual_cost) AS cost
FROM spending_item pr 
JOIN org pc ON pr.org_id=pc.code 
GROUP BY org_id, org_name, org_postcode

但是,按名称和邮政编码以及代码进行分组似乎很奇怪。感觉就像分组代码一样安全,因为没有"独特在一起"对代码,名称和邮政编码的约束。但是,如果我从org_name子句中删除org_postcodeGROUP BY,那么我会收到错误消息。

我想在实践中,由于代码是主键,这没关系。但如果它不是什么呢?我冒着为同一个代码和月份创建多行的风险。

基本上我的问题是:是否有任何加入代码的方式,只有然后使用名称和邮政编码注释输出 - 如果有多个名称和邮政编码,我会收到错误相同的代码?

这似乎比对所有三个字段进行分组更安全,并且冒着意外的风险,无形地为同一个月和代码创建多行输出。

或者我不担心什么?

1 个答案:

答案 0 :(得分:2)

您可以在selectfrom中使用子查询。当您在其中一个表中有很多列时,这非常方便。例如,以下内容将添加cost并保留pc中的所有列:

SELECT pc.*, pr.cost
FROM org pc JOIN
     (SELECT pr.org_id, SUM(pr.actual_cost) as cost
      FROM spending_item pr 
      GROUP BY pr.org_id
     ) pr
     ON pr.org_id = pc.code ;

但请注意,如果pc.code被定义为主键或唯一键,那么您也可以写:

SELECT pc.*, SUM(pr.actual_cost) AS cost
FROM org pc JOIN
     spending_item pr 
     ON pr.org_id = pc.code 
GROUP BY pc.code;

这是ANSI标准语法,只有Postgres完全支持。