简体   繁体   中英

SQL - Difference between two queries

I have two SQL queries that get the average temperature of a countries states and for the country overall, for each year:

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

What I want to do is calculate the differences between the state and national for each year. So for example:

National data

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

and State Data :

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

Would yield:

Difference

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

I've tried doing something like this but it doesn't produce the right answer.

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'

One approach which might work here would be to put your two queries into subqueries and join them on the year:

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

The above query has a bit of a hack feeling to it. To cover the case of a year appearing in one table but not the other we would have to resort to either a full outer join or an ugly union query. And in any case we might have to use a calendar table to cover years which are completely missing. I feel that a better data model would be to just store all data in a single table, at the month level. Then, an annual average could be had by just aggregating over all months in a given year.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM