创建查询以将单个列中的不同值减去新列

时间:2017-04-10 19:14:08

标签: postgresql plpgsql

标题措辞不佳,但我想不出用简洁的方式来描述我的问题。

我有一个包含以下列的表:

year | month | basin_id | value

我需要获取一年/月的所有basin_id的值,并从中减去另一年/月的所有basin_id的相应值,并将结果值存储为仍与其各自相关联的值basin_ids。

这看起来应该是一个相当简单的查询/子查询,我可以用以下方法计算值的差异:

SELECT (val1.value-val2.value)
FROM value_table_1 as val1, 
     value_table_2 as val2 
WHERE val1.basin_id=val2.basin_id

其中value_table_1和value_table_2是临时表,我通过隔离与year1 / month1和year2 / month2相关的所有值来简化我的查询。

我的问题是,我得到一个包含所有新值的列,但不包含相关联的盆。我怎样才能做到这一点?我在plpgsql存储过程中写这个,如果有帮助的话。

说我的表如下:

year | month | basin_id | value
-----+-------+----------+-------
2017 |   04  |   123    |  10
2017 |   04  |   456    |  6
2017 |   05  |   123    |  12
2017 |   05  |   456    |  4

我得到了输入:

year1 := 2017
month1 := 04
year2 := 2017
month2 := 05

我希望得到下表:

 basin_id | value
----------+------
   123    |  -2
   456    |  2

1 个答案:

答案 0 :(得分:1)

我想你想要这样的事情......

CREATE TABLE foo
AS
  SELECT *
  FROM ( VALUES
    ( 2010, 02, 5, 8 ),
    ( 2013, 05, 5, 3 )
  ) AS t( year, month, basinid, value );

CREATE TEMPORARY TABLE bar
AS
  SELECT basinid,
    f1.year AS f1y, f1.month AS f1m,
    f2.year AS f2y, f2.month AS f2m,
    f1.value-f2.value AS value
  FROM foo AS f1
  INNER JOIN foo as f2
    USING (basinid);

 basinid | f1y  | f1m | f2y  | f2m |     value
---------+------+-----+------+-----+----------
       5 | 2010 |   2 | 2010 |   2 |        0
       5 | 2010 |   2 | 2013 |   5 |        5
       5 | 2013 |   5 | 2010 |   2 |       -5
       5 | 2013 |   5 | 2013 |   5 |        0
(4 rows)

SELECT *
FROM bar
WHERE f1y = 2013
  AND f1m = 5
  AND f2y = 2010
  AND f2m = 2;