2017-09-19 10 views
1

J'ai deux requêtes SQL qui obtiennent la température moyenne d'un États pays et pour l'ensemble du pays, pour chaque année:SQL - Différence entre deux requêtes

SELECT strftime('%Y', date) as valYear, AVG(averageTemperature) 
FROM state 
WHERE country = 'Africa' 
GROUP BY valYear 

SELECT strftime('%Y', date) as valYear, AVG(averageTemperature) 
FROM country 
WHERE country = 'Africa' 
GROUP BY valYear 

Ce que je veux faire est de calculer les différences entre l'état et national pour chaque année. Ainsi, par exemple:

Les données nationales

Year AverageTemp 
----------------- 
1954 17.5 
1955 18 

et État des données:

Year AverageTemp 
----------------- 
1954 15.5 
1955 15 

céderais:

Différence

 Year Diff 
    ----------- 
    1954 2 
    1955 3 

J'ai essayé de faire quelque chose comme ça, mais ça ne donne pas la bonne réponse.

SELECT 
    s.date, (c.averageTemperature - s.averageTemperature) AS Difference 
FROM 
    state s 
INNER JOIN 
    country c ON s.date = c.date 
WHERE 
    s.country = 'Africa' AND c.country = 'Africa' 

Répondre

3

Une approche qui pourrait travailler ici serait de mettre vos deux requêtes en sous-requêtes et les rejoindre à l'année:

SELECT 
    t1.valYear, 
    t1.avgTemp - t2.avgTemp AS Diff 
FROM 
(
    SELECT 
     strftime('%Y', date) AS valYear, 
     AVG(averageTemperature) AS avgTemp 
    FROM country 
    WHERE country = 'Africa' 
    GROUP BY valYear 
) t1 
INNER JOIN 
(
    SELECT 
     strftime('%Y', date) AS valYear, 
     AVG(averageTemperature) AS avgTemp 
    FROM state 
    WHERE country = 'Africa' 
    GROUP BY valYear 
) t2 
    ON t1.valYear = t2.valYear 

La requête ci-dessus a un peu un hack sentiment à elle. Pour couvrir le cas d'une année apparaissant dans une table mais pas dans l'autre, nous aurions à recourir à une jointure externe complète ou à une requête syndicale laide. Et dans tous les cas, nous pourrions avoir à utiliser une table de calendrier pour couvrir les années qui manquent complètement. Je pense qu'un meilleur modèle de données consisterait simplement à stocker toutes les données dans une seule table, au niveau du mois. Ensuite, une moyenne annuelle pourrait être obtenue en agrégeant simplement sur tous les mois dans une année donnée.

1
SELECT s.valYear, (c.average - s.average) AS Difference 
FROM (SELECT EXTRACT(YEAR FROM date) AS valYear, AVG(averageTemperature) AS average 
     FROM state WHERE country = 'Africa' GROUP BY valYear 
    ) AS s, 
    (SELECT EXTRACT(YEAR FROM date) AS valYear, AVG(averageTemperature) AS average 
     FROM country WHERE country = 'Africa' GROUP BY valYear 
    ) AS c 
WHERE s.valYear = c.valYear