Structured Query Language



index
Disabled back button Next Section
printable version

Section 0: Module Objectives or Competencies
Course Objective or Competency Module Objectives or Competency
The student will be able to create database and table structures using the SQL data definition commands. The student will be able to apply the CREATE SCHEMA or CREATE DATABASE commands to create database structures.
The student will be able to apply the CREATE TABLE command to create table structures.
The student will be able to apply various other SQL commands to get a description of table structures or to generate a list of all tables in the database.
The student will be able to enter, correct, delete, and update data within database tables using the SQL data management commands. The student will be able to utilize the INSERT command to enter data into a database table.
The student will be able to apply the UPDATE command to make changes in the data.
The student will be introduced to the WHERE clause, which is used to specify conditions that must be met by a tuple's data in order for that tuple to be affected by the query.
The student will be able to apply the DELETE command to delete table rows.
The student will be able to apply the COMMIT command to save the table contents.
The student will be able to apply the ROLLBACK command to restore a database to its previous state.
The student will be able to explore database contents and convert data to information using the SQL data query commands. The student will be able to apply the SELECT command to list the table contents.
The student will be introduced to the WHERE clause, which can be used in conjunction with the SELECT command to limit the table contents included in the output.
The student will be able to apply relational (or comparison) operators to determine if one operand is greater than, less than, equal to, or not equal to another operand in the condition of a WHERE clause.
The student will be able to apply logical operators to connect two or more expressions in a WHERE clause such that the value of the compound expression produced depends only on that of the original expressions and on the selected operator.
The student will be able to apply arithmetic operators to perform arithmetic on table attributes and numerical values in a WHERE clause to return a single value.
The student will be able to apply the advanced comparison operators "BETWEEN", "IS NULL", "LIKE", "IN", and "EXISTS" to enhance the search capabilities of a SQL query.
The student will be able to apply various types of SQL JOIN operations to combine related rows from two tables into single virtual tables. The student will also be able to explain why the JOIN is the power behind a relational database. The student will be able to apply an INNER JOIN using the WHERE clause.
The student will be able to apply an INNER JOIN using the INNER JOIN ON keywords.
Section 1: Overview of the Structured Query Language

Structured Query Language (SQL) pronounced as "S-Q-L" or sometimes as "Sequel" is the standard language for dealing with Relational Databases

Overview

Justification

Programmers, database administrators, and business analysts alike use SQL to access information.

Learning SQL increases your marketability. Some of the most common positions that require knowledge of SQL include:

Technological Uses

SQL has countless technological uses

Here are some additional applications of SQL:

Database? Meh...

Knowledge of database concepts is critical. StackOverflow Insights explains that technologies cluster together into related ecosystems that tend to be used by the same developers.

How technologies are connected.

Clearly SQL knowledge is vital to multiple technology ecosystems.

Section 2: Categories of Commands

SQL commands fall into three categories:

  1. Data definition – commands to create database and table structures

    CREATE DATABASE <database name>
    CREATE TABLE <table name>

  2. Data management – commands to enter, correct, delete, and update data within database tables

    INSERT
    COMMIT
    UPDATE
    DELETE
    ROLLBACK

  3. Data query – commands to explore database contents and convert data to information

    SELECT

Section 3: Data Types
Common SQL Data Types

Here is a description of the Numeric types supported by MySQL.

This link describes the String, or Character, types supported in MySQL.

MySQL supports Date and Time types as well.

MySQL does not have built-in Boolean type, but uses TINYINT(1) instead. MySQL provides BOOLEAN or BOOL as the synonym of TINYINT(1).


SELECTING DATA TYPES

While determining the appropriate data type is typically fairly obvious, what about numeric data like zip codes, phone number, credit card number, or social security number?

Section 4: Data Definition

Creating Database Structure

CREATE SCHEMA AUTHORIZATION <creator>;

...or...

CREATE DATABASE <database name>;


Creating Table Structure

CREATE TABLE <table name> (
attr1 char1 spec_req1,
attr2 char2 spec_req2,
  .
  .
attrn charn spec_reqn );


The following examples are based on this database model:

database model for data definition

1:M Example: CUSTOMER table

CREATE TABLE CUSTOMER (
CUS_CODE INTEGER PRIMARY KEY,
CUS_LNAME VARCHAR(15) NOT NULL,
CUS_FNAME VARCHAR(15) NOT NULL,
CUS_INITIAL CHAR(1),
CUS_AREACODE CHAR(3),
CUS_PHONE CHAR(8) NOT NULL,
CUS_BALANCE NUMERIC(9,2) DEFAULT 0.00,
CONSTRAINT CUS_UNIQUE_FIELDS UNIQUE(CUS_LNAME,CUS_FNAME, CUS_PHONE));

Note that the CREATE TABLE command allows constraints to be defined in two different places:

The preceding SQL command results in the following table:

Customer table.


1:M Example: INVOICE table

CREATE TABLE INVOICE (
INV_NUMBER INTEGER PRIMARY KEY,
CUS_CODE INTEGER NOT NULL,
INV_DATE DATETIME NOT NULL,
CONSTRAINT FOREIGN KEY (CUS_CODE) REFERENCES CUSTOMER(CUS_CODE));

Since the INVOICE table's foreign key, CUS_CODE, comes from the CUSTOMER table's primary key, the INVOICE table must be created after the CUSTOMER table.

The preceding SQL command results in the following table:

Invoice table.


1:M Example: VENDOR table

CREATE TABLE VENDOR (
V_CODE INTEGER NOT NULL UNIQUE,
V_NAME VARCHAR(35) NOT NULL,
V_CONTACT VARCHAR(15) NOT NULL,
V_AREACODE CHAR(3) NOT NULL,
V_PHONE CHAR(8) NOT NULL,
V_STATE CHAR(2) NOT NULL,
V_ORDER CHAR(1) NOT NULL,
PRIMARY KEY (V_CODE));

Notice that a different syntax is used to create this primary key.

The preceding SQL command results in the following table:

Vendor table.


1:M Example: PRODUCT table

CREATE TABLE PRODUCT (
P_CODE VARCHAR(10) PRIMARY KEY,
P_DESCRIPT VARCHAR(35) NOT NULL,
P_INDATE DATETIME NOT NULL,
P_QOH INTEGER NOT NULL,
P_MIN INTEGER NOT NULL,
P_PRICE NUMERIC(8,2) NOT NULL,
P_DISCOUNT NUMERIC(4,2) NOT NULL,
V_CODE INTEGER,
CONSTRAINT FOREIGN KEY (V_CODE) REFERENCES VENDOR (V_CODE));

Again, the VENDOR table has to be created before the PRODUCT table, because the primary key of the VENDOR table appears as a foreign key in the PRODUCT table.

The preceding SQL command results in the following table:

Product table.


M:N Example: LINE table

CREATE TABLE LINE (
INV_NUMBER INTEGER NOT NULL,
LINE_NUMBER NUMERIC(2,0) NOT NULL,
P_CODE VARCHAR(10) NOT NULL,
LINE_UNITS NUMERIC(9,2) DEFAULT 0.00 NOT NULL,
LINE_PRICE NUMERIC(9,2) DEFAULT 0.00 NOT NULL,
PRIMARY KEY (INV_NUMBER,LINE_NUMBER),
FOREIGN KEY (INV_NUMBER) REFERENCES INVOICE (INV_NUMBER) ON DELETE CASCADE,
FOREIGN KEY (P_CODE) REFERENCES PRODUCT(P_CODE),
CONSTRAINT UNIQUE (INV_NUMBER, P_CODE));

The LINE table is a composite entity or associative entity because the LINE table is required to model the M:N relationship between INVOICE and PRODUCT.

The preceding SQL command results in the following table:

LINE table.



1:1 Example: EMPLOYEE and PILOT tables

In the discussion of supertypes and subtypes and elsewhere, we encountered 1:1 relationships.

CREATE TABLE IF NOT EXISTS EMPLOYEE (
EMP_NUM INT NOT NULL,
EMP_LNAME VARCHAR(15),
EMP_FNAME VARCHAR(15),
EMP_INITIAL VARCHAR(1),
EMP_HIRE_DATE DATETIME,
EMP_TYPE VARCHAR(10),
CONSTRAINT PRIMARY KEY (EMP_NUM)
);

CREATE TABLE PILOT (
EMP_NUM INT NOT NULL,
PIL_LICENSE VARCHAR(25) NOT NULL,
PIL_RATINGS VARCHAR(25),
PIL_MED_TYPE VARCHAR(1),
CONSTRAINT PRIMARY KEY (EMP_NUM),
CONSTRAINT FOREIGN KEY (EMP_NUM) REFERENCES EMPLOYEE
);





Here is a script for table creation: script



Notes:

Copying a Table's Structure: Shallow Cloning

Shallow cloning creates a copy of an existing table data structure and column attributes without the data being copied. This will create an empty table based on the structure of the original table.

CREATE TABLE new_table LIKE original_table;


To get a description of a table's structure, use the DESCRIBE command.

DESCRIBE PRODUCT;


To get a list of all tables in a database, use the SHOW TABLES command.

SHOW TABLES IN SPRINGCATALOG;


If you are using MySQL, attribute names with a hash mark (#), like emp#, will cause problems if you do not enclose them in backquotes (the key to the left of the 1/! on your keyboard), like `emp#`.

Section 5: Data Management

DATA ENTRY

SQL requires the use of the INSERT command to enter data into the table.

INSERT lets you insert data into the table, one row at a time. It is used to make the first data entry into a new table structure or to add data to a table that already contains data.

(NOTE that SQL data entry is not noted for ease of use, so the input utilities available with the RDBMS are preferred.)

INSERT INTO PRODUCT
VALUES ('11-QER/31', 'Power Painter, 15 psi., 3 nozzle', '2015-11-03', 8, 5, 109.99, 0.00, 25595);

INSERT INTO PRODUCT (P_CODE, P_DESCRIPT, P_INDATE, P_QOH, P_MIN, P_PRICE, P_DISCOUNT, V_CODE)
VALUES ('13-Q2/P2', '7.25-in. pwr. saw blade', '2015-12-13', 32, 15, 14.99, 0.05, NULL);

Notes:

Section 6: Data Queries

CHECKING TABLE CONTENTS

The SELECT command lists the table contents. SELECT can be followed by a set of all attributes to be listed or by the wildcard symbol * if all attributes are to be listed.

SELECT * FROM PRODUCT;

...or...

SELECT P_DESCRIPT, P_INDATE, P_PRICE, ..., V_CODE
FROM PRODUCT;

Notes:




The following Learn Basic SQL in 10 Minutes video provides a very clear explanation of SELECT statements. And be sure to check out the fancy logo!




PARTIAL LISTING OF TABLE CONTENTS

The WHERE clause can be used in conjunction with the SELECT command to limit the table contents included in the output:

SELECT <column(s)>
FROM <table name>
WHERE <conditions>;

Example:

SELECT P_DESCRIPT, P_INDATE, P_PRICE, V_CODE
FROM PRODUCT
WHERE V_CODE = 21344;

Query results.
Section 7: Data Queries – Relational Operators

Relational (comparison) operators can also be used to test for the truth of some condition. Comparison operators return a Boolean data type with a value of TRUE, FALSE, or UNKNOWN.

Relational operators.

Example:

SELECT P_DESCRIPT, P_QOH, P_PRICE, V_CODE
FROM PRODUCT
WHERE V_CODE <> 21344;

Query results.


Example:

SELECT P_DESCRIPT, P_QOH, P_MIN, P_PRICE
FROM PRODUCT
WHERE P_PRICE <= 10;

Query results.


Example:

SELECT P_CODE, P_DESCRIPT, P_QOH, P_MIN, P_PRICE
FROM PRODUCT
WHERE P_CODE < '1558-QW1';

Query results.

Notes:

Example:

Task: list all records in which the stock dates occur on or after January 20, 2016.

SELECT P_DESCRIPT, P_QOH, P_MIN, P_PRICE, P_INDATE
FROM PRODUCT
WHERE P_INDATE >= '2016-01-20';

Query results.
Section 8: Data Queries – Logical Operators

SQL allows the use of the logical operators NOT, AND, and OR to test for the truth of some condition. Logical operators, like comparison operators, return a Boolean data type with a value of TRUE, FALSE, or UNKNOWN.

Example:

Task: list records with a V_CODE field of either 21344 or 24288.

SELECT P_DESCRIPT, P_INDATE, P_PRICE, V_CODE
FROM PRODUCT
WHERE V_CODE = 21344 OR V_CODE = 24288;

Query results.

Example:

Task: list all rows for which the PRICE is less than $50.00 and for which P_INDATE occurs on or after January 20, 2016.

SELECT P_DESCRIPT, P_INDATE, P_PRICE, V_CODE
FROM PRODUCT
WHERE P_PRICE < 50 AND P_INDATE >= '2016-01-20';

Query results.

Example:

Task: list all rows for which the vendor code is not 21344.

SELECT P_DESCRIPT, P_QOH, P_PRICE, V_CODE
FROM PRODUCT
WHERE NOT (V_CODE = 21344);

Query results.

Logical operators can be combined to place complex restrictions on the output.

Example: list all rows that meet the following conditions:

SELECT P_DESCRIPT, P_INDATE, P_PRICE, V_CODE
FROM PRODUCT
WHERE (P_PRICE < 50 AND P_INDATE >= '2016-01-20')
OR V_CODE = 24288;

Query results.
Section 9: Data Queries – Arithmetic Operators

SQL allows the use of arithmetic operators with table attributes in a column list or in a conditional expression.

Arithmetic operators.

Example:

SELECT P_DESCRIPT, P_QOH, P_PRICE, P_QOH * P_PRICE
FROM PRODUCT

Query results.

Aliases

SELECT P_DESCRIPT, P_QOH, P_PRICE, P_QOH * P_PRICE AS `TOTAL VALUE`
FROM PRODUCT

Query results.


ROUNDING

Note that any extraneous digits to the right of the decimal can be eliminated using the ROUND function, as in the following query:

SELECT P_DESCRIPT, P_QOH, P_PRICE,
ROUND(P_QOH * P_PRICE, 2) AS TOTVALUE
FROM PRODUCT



Example:

Task: list all products for which the quantity on hand is within five of the minimum quantity.

SELECT P_DESCRIPT, P_CODE, P_QOH, P_MIN
FROM PRODUCT
WHERE P_QOH < P_MIN + 5;

Query results.

Notes:

Section 10: Data Queries – Advanced Operators

There are advanced comparison keywords (sometimes referred to as "special operators" or "advanced logical operators") that are used to enhance the search capabilities of a SQL query.

BETWEEN

BETWEEN checks to see if a value is between value1 and value2 inclusive.

Example:

SELECT *
FROM PRODUCT
WHERE P_PRICE BETWEEN 50.00 and 100.00;

Lists all products with a price greater than or equal to 50 and less than or equal to 100.


Example:

SELECT P_DESCRIPT
FROM PRODUCT
WHERE P_DESCRIPT BETWEEN "B%" AND "D%";

Lists the product description for all products whose descriptions fall between 'B' and 'D', inclusive.


IS NULL

IS NULL is used to check for null attribute values.

Example:

SELECT P_CODE, P_DESCRIPT
FROM PRODUCT
WHERE V_CODE IS NULL;


LIKE

LIKE is used to check for similar character strings.

Example:

SELECT V_NAME, V_CONTACT, V_AREACODE, V_PHONE
FROM VENDOR
WHERE V_CONTACT LIKE 'Smith%';

Notes:


Example:

SELECT V_NAME, V_CONTACT, V_AREACODE, V_PHONE
FROM VENDOR
WHERE V_CONTACT NOT LIKE 'Smith%';

Notes:


Example:

SELECT V_NAME, V_CONTACT, V_AREACODE, V_PHONE
FROM VENDOR
WHERE V_CONTACT LIKE 'Sm_th%';

Notes:


IN

IN is used to check whether or not an attribute value matches any of the values contained within a set of listed values.

Example:

SELECT *
FROM PRODUCT
WHERE V_CODE IN (21344, 24288);

Returns all tuples with a V_CODE that equals 21344 or 24288.


The IN operator is especially useful when it is used in conjunction with subqueries (or nested queries).

SELECT V_CODE, V_NAME
FROM VENDOR
WHERE V_CODE IN (SELECT V_CODE FROM PRODUCT);

Notes:


NOT IN is also valid.


EXISTS

EXISTS is used to check whether an attribute has a value.

DELETE FROM PRODUCT
WHERE P_CODE EXISTS;


The EXISTS operator can be used whenever there is a requirement to execute a command based on the result of another query.

Example:

SELECT *
FROM VENDOR
WHERE EXISTS (SELECT * FROM PRODUCT WHERE P_QOH <= P_MIN);

Notes:

Section 11: Data Queries – Joining Tables

The normalization process was required to reduce anomalies and to ensure that each relation contained data about a single entity only.

The ability to combine (JOIN) tables on common attributes is one of the most important distinctions between relational databases and others.

A JOIN is performed when data are retrieved from more than one table at a time.

Visualization of Inner Join:



Another Visualization of Inner Join:

This type of JOIN is referred to as a Natural Join or an Inner Join, or maybe even an EQUI JOIN.

Syntax using WHERE:

SELECT <COLUMN1>, <COLUMN2>, ... <COLUMNn>
FROM <TABLE1>, <TABLE2>
WHERE <TABLE1>.<FOREIGN_KEY> = <TABLE2>.<PRIMARY_KEY>;

The syntax using INNER JOIN is shown in the next section.


In order to perform a successful JOIN, the source tables of the attributes listed in the SELECT are specified.




To list information from the PRODUCT and VENDOR databases, the V_CODE is used to establish the link:

Table linkage.

SELECT PRODUCT.P_DESCRIPT, PRODUCT.P_PRICE, VENDOR.V_NAME, VENDOR.V_CONTACT,VENDOR.V_AREACODE, VENDOR.V_PHONE
FROM PRODUCT, VENDOR
WHERE PRODUCT.V_CODE = VENDOR.V_CODE;

- or -

SELECT P_DESCRIPT, P_PRICE, V_NAME, V_CONTACT, V_AREACODE, V_PHONE
FROM PRODUCT, VENDOR
WHERE PRODUCT.V_CODE = VENDOR.V_CODE;

Results of JOIN.


An alias (alternate name) may be used to identify the source(s) from which the data are taken.

SELECT P_DESCRIPT, P_PRICE, V_NAME, V_CONTACT, V_AREACODE, V_PHONE
FROM PRODUCT P, VENDOR V
WHERE P.V_CODE = V.V_CODE;

A more predictable list can be generated by using the ORDER BY condition:

SELECT P_DESCRIPT, P_PRICE, V_NAME, V_CONTACT, V_AREACODE, V_PHONE
FROM PRODUCT, VENDOR
WHERE PRODUCT.V_CODE = VENDOR.V_CODE
ORDER BY P_PRICE;

Results of Another JOIN.



Task: list PRODUCT and VENDOR information for all products stocked after January 15, 2016.

SELECT P_DESCRIPT, P_PRICE, V_NAME, V_CONTACT, V_AREACODE, V_PHONE
FROM PRODUCT, VENDOR
WHERE PRODUCT.V_CODE = VENDOR.V_CODE
AND P_INDATE > '2016-01-15';

Results of JOIN.

Note that while PVC pipe, 3.5-in., 8-ft was stocked on February 20, 2016, it is not included because it has a NULL V_CODE field.




Click for my explanation of how to write a JOIN.




Video Tutorials

For supplemental explanations, view the videos below. The order in which they are listed reflects my opinion of the videos.

SQL Joins Explained (Goofy intro, but good explanation)

Follow-up Video - Discussion of Other Types of Joins (Still goofy, but good)

Three-table Join

Inner Join

Inner Join with Using




Links to Further Explanations

Section 12: Data Queries – Explicit Inner Join

The preceding type of Join is known as an Inner Join, so the SQL-92 standard introduced the SQL statement INNER JOIN.

Syntax using WHERE:

SELECT <COLUMN1>, <COLUMN2>, ... <COLUMNn>
FROM <TABLE1>, <TABLE2>
WHERE <TABLE1>.<FOREIGN_KEY> = <TABLE2>.<PRIMARY_KEY>;

Syntax using INNER JOIN:

SELECT SELECT
FROM <TABLE1> INNER JOIN <TABLE2>
ON <TABLE1>.<FOREIGN_KEY> = <TABLE2>.<PRIMARY_KEY>;

In order to convert a JOIN that uses the WHERE clause to an INNER JOIN

Remember that every INNER JOIN must be paired with an ON.

Joins between more than two tables can become fairly complicated, as seen in the examples that follow.




The following examples use the table schema below:

Sample database.


Example: Get the name of all suppliers that have shipped to London (script).

Sample database.

Using WHERE ("old style" join, implicit join):

SELECT DISTINCT Suppliers.SupplierName
FROM Suppliers, Shipments, Projects
WHERE (Suppliers.SupplierNum = Shipments.SupplierNum) AND
(Shipments.ProjectNum = Projects.ProjectNum) AND
(Projects.city = "London");

Using INNER JOIN and ON (when you are joining table1 and table2 on a column with the same name or different names in the two tables):

SELECT DISTINCT SupplierName
FROM Suppliers
INNER JOIN Shipments ON Suppliers.SupplierNum = Shipments.SupplierNum
INNER JOIN Projects ON Shipments.ProjectNum = Projects.ProjectNum
WHERE Projects.city = "London";

Using INNER JOIN and USING (USING is simply a shortcut when you are joining table1 and table2 on a column with the same name in both tables):

SELECT DISTINCT SupplierName
FROM Suppliers
INNER JOIN Shipments USING(SupplierNum)
INNER JOIN Projects USING(ProjectNum)
WHERE Projects.city = "London";





Example: List all those parts supplied by a supplier to a project in the same city:

Sample database.

Using WHERE:

SELECT DISTINCT Shipments.partNum, Suppliers.supplierNum, Projects.projectNum, Projects.city, Suppliers.city, Parts.city
FROM Parts, Shipments, Projects, Suppliers
WHERE (Parts.partNum = Shipments.partNum) AND
(Shipments.projectNum = Projects.projectNum) AND
(Shipments.SupplierNum = Suppliers.SupplierNum) AND
(Suppliers.city = Projects.city) and (Suppliers.city = Parts.city);

Using INNER JOIN:

SELECT DISTINCT Shipments.PartNum, Suppliers.SupplierNum, Projects.ProjectNum, Projects.City, Suppliers.City, Parts.City
FROM Parts
INNER JOIN Shipments ON (Parts.partNum = Shipments.partNum)
INNER JOIN Projects ON (Shipments.projectNum = Projects.projectNum)
INNER JOIN Suppliers ON (Shipments.SupplierNum = Suppliers.SupplierNum)
WHERE (Suppliers.city = Projects.city) and (Suppliers.city = Parts.city);

Using USING:

SELECT DISTINCT Shipments.PartNum, Suppliers.SupplierNum, Projects.ProjectNum, Projects.City, Suppliers.City, Parts.City
FROM Parts
INNER JOIN Shipments USING (partNum)
INNER JOIN Projects USING (projectNum)
INNER JOIN Suppliers USING (SupplierNum)
WHERE (Suppliers.city = Projects.city) and (Suppliers.city = Parts.city);

The Inner Join returns records that have matching values in both tables.

Access Predicates

The access predicates are the start and stop conditions for an index lookup. They define the scanned index range.

Canadian Zip Codes

Canadian zip codes are composed of two distinct parts, which specify where the mail should be delivered. The first half of the postal code is the "Forward Sorting Area" (FSA). The first letter in the first half refers to a major province or district; only Ontario and Quebec, the two largest provinces in Canada, have more than one district. The digit that comes after is the territory: 0 represents a rural location, and other other number denotes an urban location. The final letter of the FSA corresponds to the name of the district in a city or village.

The "Local Delivery Unit" (LDU) forms the second part of the zip code. This combination of three letters and/or numbers indicates the dispatch location for the mail from a given FSA. The LDU is used for final sorting. It is a service point that is shared by a group of houses and/or businesses.