2017-04-10 4 views
1

Titre mal rédigé, mais je ne peux pas trouver une façon succincte de décrire mon problème.Création d'une requête pour soustraire des valeurs différentes d'une seule colonne dans une nouvelle colonne

J'ai une table avec les colonnes suivantes:

year | month | basin_id | value 

Je dois prendre les valeurs pour tous les basin_ids d'un an/mois et soustraire les valeurs correspondantes pour tous les basin_ids d'une autre année/mois, et stocker les valeurs résultantes de telle sorte qu'elles sont toujours associées à leur basin_ids respectif.

Cela semble qu'il devrait être une question assez simple/sous-requête, et je peux calculer la différence des valeurs très bien avec:

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

où value_table_1 et value_table_2 sont des tables temporaires que j'ai fait par tous les séparer Les valeurs associées à year1/month1 et year2/month2 dans le but de simplifier ma requête.

Mon problème ici est que j'obtiens une colonne avec toutes les nouvelles valeurs, mais pas avec leurs bassins associés. Comment puis-je atteindre cet objectif? J'écris ceci dans une procédure stockée de plpgsql, si cela aide.

Dites ma table est la suivante:

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

et je me donne les entrées:

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

Je veux obtenir le tableau suivant à la suite:

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

Modifiez votre question et fournissez des exemples de données et les résultats souhaités. –

Répondre

1

Je pense que vous voulez quelque chose comme ça ..

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; 
+0

Cela ressemble exactement à ce dont j'ai besoin. Merci beaucoup, j'accepterai la réponse quand elle me le permettra. –

+1

Désolé une dernière question - comment puis-je donner un nom à la dernière colonne de valeurs pour que je puisse l'interroger? EDIT: nevermind, vient d'ajouter "as value" à la fin de l'instruction "f1.value-f2.value" –