SQL Syntex
SQL Syntex
CITY
Phoenix
Denver
Caribou
STATE
AZ
CO
ME
LAT_N
33
40
47
LONG_W
112
105
68
CITY
Denver
Caribou
STATE
CO
ME
LAT_N
40
47
LONG_W
105
68
CITY
Phoenix
Denver
Caribou
STATE
AZ
CO
ME
CITY
STATE
Denver
Caribou
CO
ME
MONTH
TEMP_F
1
7
1
7
1
7
RAIN_I
57.4
91.7
27.3
74.8
6.7
65.8
.31
5.15
.18
2.11
2.1
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
13
13
44
44
66
66
CITY
Phoenix
Phoenix
Denver
Denver
Caribou
Caribou
ST
AZ
AZ
CO
CO
ME
ME
LAT_N
33
33
40
40
47
47
LONG_W
112
112
105
105
68
68
ID
13
13
44
44
66
66
MONTH
1
7
1
7
1
7
TEMP_F
57.4
91.7
27.3
74.8
6.7
65.8
RAIN_I
.31
5.15
.18
2.11
2.1
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
1 66
1 13
1 44
7 13
7 66
7 44
TEMP_F
2.1
.31
.18
5.15
4.52
2.11
6.7
57.4
27.3
91.7
65.8
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
40
33
Caribou
Denver
Phoenix
65.8
74.8
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)
91.7
74.8
65.8
AVG(RAIN_I)
57.4
27.3
6.7
ID
2.73 13
1.145 44
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
13
44
CITY
Phoenix
Denver
ST
AZ
CO
LAT_N
33
40
LONG_W
112
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
13
13
44
44
66
66
TEMP_C
1
7
1
7
1
7
RAIN_C
14.1111111
33.1666667
-2.6111111
23.7777778
-14.055556
18.7777778
.122047
2.027555
.070866
.830707
.82677
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
44
66
MONTH
1
1
TEMP_C
-2.6111111
-14.055556
RAIN_C
.070866
.82677
MONTH
TEMP_F
1
7
1
7
1
7
RAIN_I
57.4
91.7
27.3
74.8
6.7
65.8
update one row, Denver's July temperature reading, to correct a data entry error:
.32
5.16
.19
2.12
2.11
4.53
MONTH
13
13
44
44
66
66
TEMP_F
1
7
1
7
1
7
RAIN_I
57.4
91.7
27.3
74.9
6.7
65.8
.32
5.16
.19
2.12
2.11
4.53
MONTH
TEMP_F
1
7
1
7
1
7
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:
RAIN_I
57.4
91.7
27.3
74.9
6.7
65.8
.32
5.16
4.5
4.5
2.11
4.53
MONTH
13
13
44
44
66
66
TEMP_F
1
7
1
7
1
7
RAIN_I
57.4
91.7
27.3
74.9
6.7
65.8
.32
5.16
.19
2.12
2.11
4.53
MONTH
TEMP_F
1
7
1
7
1
7
RAIN_I
57.4
91.7
27.3
74.9
6.7
65.8
.32
5.16
.19
4.5
2.11
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:
CITY
Phoenix
Denver
ST
LAT_N
AZ
CO
33
40
LONG_W
112
105
MONTH
1
1
TEMP_F
57.4
27.3
RAIN_I
.32
.19
MONTH
1
1
TEMP_C
14.1111111
-2.6111111
RAIN_C
.125984
.074803
If we want only specific columns (as is usually the case), we can/should explicitly specify them in a commaseparated list, as in
which results in the specified fields of data for all of the rows in the table:
Explicitly specifying the desired fields also allows us to control the order in which the fields are returned, so that if
we wanted the last name to appear before the first name, we could write
resulting in
If you wanted to get the opposite, the employees who do not live in London, you would write
It is not necessary to test for equality; you can also use the standard equality/inequality operators that you would
expect. For example, to get a list of employees who where hired on or after a given date, you would write
Of course, we can write more complex conditions. The obvious way to do this is by having multiple conditions in
the WHERE clause. If we want to know which employees were hired between two given dates, we could write
SELECT
FROM
WHERE
resulting in
Note that SQL also has a special BETWEEN operator that checks to see if a value is between two values (including
equality on both ends). This allows us to rewrite the previous query as
SELECT
FROM
WHERE
We could also use the NOT operator, to fetch those rows that are not between the specified dates:
SELECT
FROM
WHERE
Let us finish this section on the WHERE clause by looking at two additional, slightly more sophisticated,
comparison operators.
What if we want to check if a column value is equal to more than one value? If it is only 2 values, then it is easy
enough to test for each of those values, combining them with theOR operator and writing something like
However, if there are three, four, or more values that we want to compare against, the above approach quickly
becomes messy. In such cases, we can use the IN operator to test against a set of values. If we wanted to see if
the City was either Seattle, Tacoma, or Redmond, we would write
As with the BETWEEN operator, here too we can reverse the results obtained and query for those rows where
City is not in the specified list:
SELECT EmployeeID, FirstName, LastName, HireDate, City FROM Employees
WHERE City NOT IN ('Seattle', 'Tacoma', 'Redmond')
Finally, the LIKE operator allows us to perform basic pattern-matching using wildcard characters. For Microsoft
SQL Server, the wildcard characters are defined as follows:
Wildcard
Description
_ (underscore)
[]
matches any single character within the specified range (e.g. [a-f]) or set (e.g. [abcde
[^]
matches any single character not within the specified range (e.g. [^a-f]) or set (e.g. [^
WHERE FirstName LIKE '_im' finds all three-letter first names that end with 'im' (e.g. Jim, Tim).
WHERE LastName LIKE '%stein' finds all employees whose last name ends with 'stein'
WHERE LastName LIKE '%stein%' finds all employees whose last name includes 'stein' anywhere in the
name.
WHERE FirstName LIKE '[JT]im' finds three-letter first names that end with 'im' and begin with either 'J' or
'T' (that is, only Jim and Tim)
WHERE LastName LIKE 'm[^c]%' finds all last names beginning with 'm' where the following (second)
letter is not 'c'.
Here too, we can opt to use the NOT operator: to find all of the employees whose first name does not start with
'M' or 'A', we would write
resulting in
By default, the sort order for a column is ascending (from lowest value to highest value), as shown below for the
previous query:
If we want the sort order for a column to be descending, we can include the DESC keyword after the column
name.
The ORDER BY clause is not limited to a single column. You can include a comma-delimited list of columns to sort
bythe rows will all be sorted by the first column specified and then by the next column specified. If we add the
Country field to the SELECT clause and want to sort by Country and City, we would write:
Note that to make it interesting, we have specified the sort order for the City column to be descending (from
highest to lowest value). The sort order for the Country column is still ascending. We could be more explicit about
this by writing
but this is not necessary and is rarely done. The results returned by this query are
It is important to note that a column does not need to be included in the list of selected (returned) columns in
order to be used in the ORDER BY clause. If we don't need to see/use the Country values, but are only interested
in them as the primary sorting field we could write the query as
COUNT(*)
----------
1 row selected.
COUNT(PROD_ID)
---------------
1 row selected.
1.
SELECT column-names
2.
FROM table-name1
3.
4.
5.
1.
2.
column-names
3.
FROM table-name
4.
WEHRE condition
ORDERITEM
Id
OrderId
ProductId
UnitPrice
Quantity
PRODUCT
Id
ProductName
SupplierId
UnitPrice
Package
IsDiscontinued
1.
2.
3.
SELECT ProductName
FROM Product
WHERE Id IN (SELECT ProductId
4.
FROM OrderItem
5.
Results: 12 records
PoductName
Guaran Fantstica
Schoggi Schokolade
Chartreuse verte
Jack's New England Clam Chowder
Rogede sild
Manjimup Dried Apples
Perth Pasties
CUSTOMER
Id
FirstName
LastName
City
Country
Phone
ORDER
Id
OrderDate
OrderNumber
CustomerId
TotalAmount
1.
SELECT ProductName
2.
3.
4.
FROM Product
WHERE Id = ANY
(SELECT ProductId
5.
6.
FROM OrderItem
WHERE Quantity = 1)