Postgres,添加GROUP BY记录的值的总和

时间:2017-11-24 16:09:04

标签: postgresql subquery

尝试编写一个查询,该查询将获取已连接表的列status

的总和

我加入的两个表格是missionmedia。任务记录可以有0 - > n个媒体记录。

目前我的查询会返回这样的结果。

e.g。

id      job_id  date        lat             long                status
1893    HAM267  13:53:42    51.501671242483 -0.22951886283813   2
1893    HAM267  13:53:42    51.501577520364 -0.22880621040992   1
1893    HAM267  13:53:42    51.50137231105  -0.22878203293347   0
1893    HAM267  13:53:42    51.501506139391 -0.22880008494156   2

但是,我想对所有相关媒体记录进行分组,并添加其status列值。

1893    HAM267  13:53:42    51.501671242483 -0.22951886283813   5

我尝试对子查询进行求和,然后按每列进行分组,但是这不会产生错误所需的效果:

  

[21000]错误:用作表达式

的子查询返回多行

查询

SELECT
  mis.id                                                         AS "ID",
  mis.job_id                                                     AS "Job ID",
  to_char(mis.date, 'DD/MM/YYYY')                                AS "Date",
  med.location_latitude                                          AS "Lat",
  med.location_longitude                                         AS "Long",
  (select sum(med.status) from media where med.mission_id = mis.id)  AS "Status Aggregate"
FROM mission mis
  LEFT JOIN media med
    ON mis.id = med.mission_id
GROUP BY mis.id, med.location_longitude, med.location_latitude, med.mission_id, med.state, med.file_path;

1 个答案:

答案 0 :(得分:1)

由于您未提供有关如何检索纬度和经度的任何信息,我将分别为每个查询提供last_valuemax

--Sample
CREATE TEMP TABLE mission 
    (id, job_id, date) AS
    VALUES 
        (1893, 'HAM267'::TEXT, now()),
        (1894, 'XYZ', now());

CREATE TEMP TABLE media 
    (id, mission_id, location_latitude, location_longitude, status) AS
    VALUES 
        (1, 1893, 51.501671242483, -0.22951886283813, 2),
        (2, 1893, 51.501577520364, -0.22880621040992, 1),
        (3, 1893, 51.50137231105, -0.22878203293347, 0),
        (4, 1893, 51.501506139391, -0.22880008494156, 2),
        (5, 1894, 51.501671242466, -0.22951886283812, 7);

--Using DISTINCT ON. 
--You should add ORDER BY clause in OVER to avoid unpredictable results
SELECT
    DISTINCT ON (mis.id, mis.job_id, mis.date)
    mis.id AS "ID",
    mis.job_id AS "Job ID",
    to_char(mis.date, 'DD/MM/YYYY') AS "Date",
    first_value(med.location_latitude) 
        OVER(PARTITION BY mis.id, mis.job_id, mis.date) AS "Lat", 
    first_value(med.location_longitude) 
        OVER(PARTITION BY mis.id, mis.job_id, mis.date) AS "Long",
    sum(med.status) 
        OVER(PARTITION BY mis.id, mis.job_id, mis.date) AS "Status Aggregate"                                       
FROM mission mis
  LEFT JOIN media med
    ON mis.id = med.mission_id
ORDER BY
    mis.id, mis.job_id, mis.date;

--Using GROUP 
SELECT
    mis.id AS "ID",
    mis.job_id AS "Job ID",
    to_char(mis.date, 'DD/MM/YYYY') AS "Date",
    max(med.location_latitude) AS "Lat",
    max(med.location_longitude) AS "Long",
    sum(med.status) AS "Status Aggregate"                                       
FROM mission mis
  LEFT JOIN media med
    ON mis.id = med.mission_id
GROUP BY
    mis.id, mis.job_id, mis.date
ORDER BY
    mis.id, mis.job_id, mis.date;