create a table to store information about weather observation stations:
-- No duplicate ID fields allowed
CREATE TABLE STATION
(ID INTEGER PRIMARY KEY,
CITY CHAR(20),
STATE CHAR(2),
LAT_N REAL,
LONG_W REAL);
populate the table STATION with a few rows:
INSERT INTO STATION VALUES (13, 'Phoenix', 'AZ', 33, 112);
INSERT INTO STATION VALUES (44, 'Denver', 'CO', 40, 105);
INSERT INTO STATION VALUES (66, 'Caribou', 'ME', 47, 68);
query to look at table STATION in undefined order:
SELECT * FROM STATION;
ID CITY STATE LAT_N LONG_W
13 Phoenix AZ 33 112
44 Denver CO 40 105
66 Caribou ME 47 68
query to select Northern stations (Northern latitude > 39.7):
-- selecting only certain rows is called a "restriction".
SELECT * FROM STATION
WHERE LAT_N > 39.7;
ID CITY STATE LAT_N LONG_W
44 Denver CO 40 105
66 Caribou ME 47 68
query to select only ID, CITY, and STATE columns:
-- selecting only certain columns is called a "projection".
SELECT ID, CITY, STATE FROM STATION;
ID CITY STATE
13 Phoenix AZ
44 Denver CO
66 Caribou ME
query to both "restrict" and "project":
SELECT ID, CITY, STATE FROM STATION
WHERE LAT_N > 39.7;
ID CITY STATE
44 Denver CO
66 Caribou ME
create another table to store normalized temperature and precipitation data:
-- ID field must match some STATION table ID
(so name and location will be known).
-- allowable ranges will be enforced for other values.
-- no duplicate ID and MONTH combinations.
-- temperature is in degrees Fahrenheit.
-- rainfall is in inches.
CREATE TABLE STATS
(ID INTEGER REFERENCES STATION(ID),
MONTH INTEGER CHECK (MONTH BETWEEN 1 AND 12),
TEMP_F REAL CHECK (TEMP_F BETWEEN -80 AND 150),
RAIN_I REAL CHECK (RAIN_I BETWEEN 0 AND 100),
PRIMARY KEY (ID, MONTH));
populate the table STATS with some statistics for January and July:
INSERT INTO STATS VALUES (13, 1, 57.4, 0.31);
INSERT INTO STATS VALUES (13, 7, 91.7, 5.15);
INSERT INTO STATS VALUES (44, 1, 27.3, 0.18);
INSERT INTO STATS VALUES (44, 7, 74.8, 2.11);
INSERT INTO STATS VALUES (66, 1, 6.7, 2.10);
INSERT INTO STATS VALUES (66, 7, 65.8, 4.52);
query to look at table STATS in undefined order:
SELECT * FROM STATS;
ID MONTH TEMP_F RAIN_I
13 1 57.4 .31
13 7 91.7 5.15
44 1 27.3 .18
44 7 74.8 2.11
66 1 6.7 2.1
66 7 65.8 4.52
query to look at table STATS, picking up location information by joining with
table STATION on the ID column:
-- matching two tables on a common column is called a "join".
-- the column names often match, but this is not required.
-- only the column values are required to match.
SELECT * FROM STATION, STATS
WHERE STATION.ID = STATS.ID;
ID CITY ST LAT_N LONG_W ID MONTH TEMP_F RAIN_I
13 Phoenix AZ 33 112 13 1 57.4 .31
13 Phoenix AZ 33 112 13 7 91.7 5.15
44 Denver CO 40 105 44 1 27.3 .18
44 Denver CO 40 105 44 7 74.8 2.11
66 Caribou ME 47 68 66 1 6.7 2.1
66 Caribou ME 47 68 66 7 65.8 4.52
query to look at the table STATS, ordered by month and greatest rainfall, with
columns rearranged:
SELECT MONTH, ID, RAIN_I, TEMP_F
FROM STATS
ORDER BY MONTH, RAIN_I DESC;
MONTH ID RAIN_I TEMP_F
1 66 2.1 6.7
1 13 .31 57.4
1 44 .18 27.3
7 13 5.15 91.7
7 66 4.52 65.8
7 44 2.11 74.8
query to look at temperatures for July from table STATS, lowest temperatures
first, picking up city name and latitude by joining with table STATION on the ID
column:
SELECT LAT_N, CITY, TEMP_F
FROM STATS, STATION
WHERE MONTH = 7
AND STATS.ID = STATION.ID
ORDER BY TEMP_F;
LAT_N CITY TEMP_F
47 Caribou 65.8
40 Denver 74.8
33 Phoenix 91.7
query to show MAX and MIN temperatures as well as average rainfall for each
station:
SELECT MAX(TEMP_F), MIN(TEMP_F), AVG(RAIN_I), ID
FROM STATS
GROUP BY ID;
MAX(TEMP_F) MIN(TEMP_F) AVG(RAIN_I) ID
91.7 57.4 2.73 13
74.8 27.3 1.145 44
65.8 6.7 3.31 66
query (with subquery) to show stations with year-round average temperature
above 50 degrees:
-- rows are selected from the STATION table based on related values in the STATS
table.
SELECT * FROM STATION
WHERE 50 < (SELECT AVG(TEMP_F) FROM STATS
WHERE STATION.ID = STATS.ID);
ID CITY ST LAT_N LONG_W
13 Phoenix AZ 33 112
44 Denver CO 40 105
create a view (derived table or persistent query) to convert Fahrenheit to Celsius
and inches to centimeters:
CREATE VIEW METRIC_STATS (ID, MONTH, TEMP_C, RAIN_C) AS
SELECT ID,
MONTH,
(TEMP_F - 32) * 5 /9,
RAIN_I * 0.3937
FROM STATS;
query to look at table STATS in a metric light (through the new view):
SELECT * FROM METRIC_STATS;
ID MONTH TEMP_C RAIN_C
13 1 14.1111111 .122047
13 7 33.1666667 2.027555
44 1 -2.6111111 .070866
44 7 23.7777778 .830707
66 1 -14.055556 .82677
66 7 18.7777778 1.779524
another metric query restricted to January below-freezing (0 Celsius) data,
sorted on rainfall:
SELECT * FROM METRIC_STATS
WHERE TEMP_C < 0 AND MONTH = 1
ORDER BY RAIN_C;
ID MONTH TEMP_C RAIN_C
44 1 -2.6111111 .070866
66 1 -14.055556 .82677
Interactive SQL Update Examples
update all rows of table STATS to compensate for faulty rain gauges known to
read 0.01 inches low:
UPDATE STATS SET RAIN_I = RAIN_I + 0.01;
and take a look:
SELECT * FROM STATS;
ID MONTH TEMP_F RAIN_I
13 1 57.4 .32
13 7 91.7 5.16
44 1 27.3 .19
44 7 74.8 2.12
66 1 6.7 2.11
66 7 65.8 4.53
update one row, Denver's July temperature reading, to correct a data entry
error:
UPDATE STATS SET TEMP_F = 74.9
WHERE ID = 44
AND MONTH = 7;
and take a look:
SELECT * FROM STATS;
ID MONTH TEMP_F RAIN_I
13 1 57.4 .32
13 7 91.7 5.16
44 1 27.3 .19
44 7 74.9 2.12
66 1 6.7 2.11
66 7 65.8 4.53
make the above changes permanent:
-- they were only temporary until now.
COMMIT WORK;
update two rows, Denver's rainfall readings:
UPDATE STATS SET RAIN_I = 4.50
WHERE ID = 44;
and take a look:
SELECT * FROM STATS;
ID MONTH TEMP_F RAIN_I
13 1 57.4 .32
13 7 91.7 5.16
44 1 27.3 4.5
44 7 74.9 4.5
66 1 6.7 2.11
66 7 65.8 4.53
Oops! We meant to update just the July reading! Undo that update:
-- undoes only updates since the last COMMIT WORK.
ROLLBACK WORK;
and take a look:
SELECT * FROM STATS;
ID MONTH TEMP_F RAIN_I
13 1 57.4 .32
13 7 91.7 5.16
44 1 27.3 .19
44 7 74.9 2.12
66 1 6.7 2.11
66 7 65.8 4.53
now update Denver's July rainfall reading and make it permanent:
UPDATE STATS SET RAIN_I = 4.50
WHERE ID = 44
AND MONTH = 7;
COMMIT WORK;
and take a look:
SELECT * FROM STATS;
ID MONTH TEMP_F RAIN_I
13 1 57.4 .32
13 7 91.7 5.16
44 1 27.3 .19
44 7 74.9 4.5
66 1 6.7 2.11
66 7 65.8 4.53
delete July data and East Coast data from both tables:
-- note that we use longitude values from the related STATION table to determine
which STAT stations were east of 90 degrees.
DELETE FROM STATS
WHERE MONTH = 7
OR ID IN (SELECT ID FROM STATION
WHERE LONG_W < 90);
DELETE FROM STATION WHERE LONG_W < 90;
COMMIT WORK;
and take a look:
SELECT * FROM STATION;
ID CITY ST LAT_N LONG_W
13 Phoenix AZ 33 112
44 Denver CO 40 105
SELECT * FROM STATS;
ID MONTH TEMP_F RAIN_I
13 1 57.4 .32
44 1 27.3 .19
View METRIC_STATS, a Fahrenheit-to-Centigrade and inches-to-centimeters
conversion of table STATS, reflects the updates made to the underlying table.
SELECT * FROM METRIC_STATS;
ID MONTH TEMP_C RAIN_C
13 1 14.1111111 .125984
44 1 -2.6111111 .074803