MySQL Database Introduction
MySQL Database Introduction
MySQL client programs: MySQL comes with many client programs. The one with which we'll be
dealing a lot is called mysql (note: smallcaps). This provides an interface through which you can issue
SQL statements and have the results displayed.
MySQL client Library: This can help you in writing client programs in C. (We won't be taking about
this in our tutorial).
4. This means that you have successfully created the database. Now, let's see how many databases
you have on your system. Issue the following command.
show databases;
Here we have three databases, two created by MySQL during installation and our employees
database.
5. To come back to the DOS prompt, type quit at the mysql prompt.
MySQL - Creating tables
In this section of the mysql course we will explore the MySQL commands to create database tables and
selecting the database.
The table above contains four columns that store the name, age, country and email. Each row contains
data for one individual. This is called a record. To find the country and email of Alexander, you'd first
pick the name from the first column and then look in the third and fourth columns of the same row.
A database can have many tables; it is tables that contain the actual data. Hence, we can segregate
related (or unrelated) data in different tables. For our employees database we'll have one table that stores
company details of the employees. The other table would contain personal information.
Let's make the first table.
The SQL command for creating tables looks complex when you view it for the first time. Don't worry if
you get confused, it shall be elaborated later in more detail.
Using a database
We've already created our employees database. Now let's start the mysql client program and select our
database. Once at the mysql prompt, issue the command:
SELECT DATABASE();
The above shows that no database has been selected. Actually, every time we work with mysql client,
we have to specify which database we plan to use. There are several ways of doing it.
Specifying the database name at the start; type the following at the system prompt:
mysql employees (under Windows)
mysql employees -u manish -p (under Linux)
Specifying the database with the USE statement at the mysql prompt:
mysql>USE employees;
It's necessary to specify the database we plan to use, else MySQL will throw an error.
Creating tables
Once you've selected the employees database, issue the CREATE TABLE command at the mysql
prompt.
Note: When you press the enter key after typing the first line, the mysql prompt changes to a ->. This
means that mysql understands that the command is not complete and prompts you for additional
statements. Remember, each mysql command ends with a semi-colon and each field declaration is
separated by a comma. Also, you can type the entire command on one line if you so want.
You screen should look similar to:
MySQL tables
Now that we've created our employee_data table, let's check its listing.
Type SHOW TABLES; at the mysql prompt. This should present you with the following display:
Describing tables
MySQL provides us with a command that displays the field details of the tables.
Issue the following command at the mysql prompt:
DESCRIBE employee_data;
OR
Desc employee_data;
+----------+----------------------+--------+----- +-----------+----------------------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------------------+--------+-------+-----------+----------------------+
| emp_id | int(10) unsigned | | PRI | 0 | auto_increment |
| f_name | varchar(20) | YES | | NULL | |
| l_name | varchar(20) | YES | | NULL | |
| title | varchar(30) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| yos | int(11) | YES | | NULL | |
| salary | int(11) | YES | | NULL | |
| perks | int(11) | YES | | NULL | |
| email | varchar(60) | YES | | NULL | |
+----------+-----------------------+--------+--------+----------+--------------------+
DESCRIBE lists all the field names along with the types of data they ought to contain in the
table.
Where table_name is the name of the table into which we want to insert data; field1, field2 etc. are
the field names and value1, value2 etc. are values for the respective field. This is quite simple.
As with other MySQL statements, you can enter this command on one line or span it in multiple
lines.
Some important points:
i. The table name is employee_data
ii. The values for columns f_name, l_name, title and email are text strings and surrounded with
quotes.
iii. Values for age, yos, salary and perks are numbers (intergers) and without quotes.
iv. You'll notice that we've inserted data in all columns except emp_id. This is because, we leave
this job to MySQL, which will check the column for the largest value, increment it by one
and insert the new value.
Once you type the above command correctly in the mysql client, it displays a success message.
Task
This (insert statement above) inserts a single record into our table. You are now required to insert 14
more records into the table, using the same format that has been used to insert the first record.
Querying MySQL tables
Our employee_data table now contains enough data for us to work with. Let us see how we can extract
(query) it. Querying involves the use of the MySQL SELECT command.
Data is extracted from the table using the SELECT SQL command. Here is the format of a SELECT
statement:
The conditions part of the statement is optional (we'll go through this later). Basically, you require to
know the field names and the table name from which to extract the data.
For example, in order to extract the first and last names of all employees, issue the following command.
The statement tells MySQL to list all the rows from fields f_name and l_name.
+-----------+------------+
| f_name | l_name |
+-----------+-------------+
| Manish | Sharma |
| John | Hagan |
| Ganesh | Pillai |
| Anamika | Pandit |
| Mary | Anchor |
| Fred | Kruger |
| John | MacFarland |
| Edward | Sakamuro |
| Alok | Nanda |
| Hassan | Rajabi |
| Paul | Simon |
| Arthur | Hoopla |
| Kim | Hunter |
| Roger | Lewis |
| Danny | Gibson |
| Mike | Harper |
| Monica | Sehgal |
| Hal | Simlai |
| Joseph | Irvine |
| Shahida | Ali |
| Peter | Champion |
+----------+-------------+
21 rows in set (0.00 sec)
On close examination, you'll find that the display is in the order in which the data was inserted.
Furthermore, the last line indicates the number of rows our table has (21).
To display the entire table, we can either enter all the column names or use a simpler form of the
SELECT statement.
Some of you might recognize the * in the above statement as the wildcard. Though we don't use that
term for the character here, it serves a very similar function. The * means 'ALL fields'. Thus, the above
statement lists all the rows of all fields.
Selecting f_name, l_name and age fields would display something like:
1. Write the complete SQL statement for creating a new database called address book
2. Which statement is used to list the information about a table? How do you use this statement?
3. How would you list all the databases available on the system?
4. Write the statement for inserting the following data in employee_data table
First name: Rudolf
Last name: Reindeer
Title: Business Analyst
Age: 34
Years of service: 2
Salary: 95000
Perks: 17000
email: [email protected]
5. Give two forms of the SELECT statement that will list all the data in employee_data table.
6. What will select f_name, email from employee_data; display?
7. Write the statement for listing data from salary, perks and yos fields of employee_data table.
8. How can you find the number of rows in a table using the SELECT statement?
9. What will select salary, l_name from employee_data; display?
MySQL - selecting data using conditions
In this section of the MySQL Manual we'll look at the format of a SELECT statement we met in the last
session in detail. We will learn how to use the select statement using the WHERE clause.
SELECT field_names from table_name [WHERE ...conditions];
Now, we know that the conditions are optional (we've seen several examples in the last session... and
you would have encountered them in the assignments too).
The SELECT statement without conditions lists all the data in the specified fields. The strength of
RDBMS lies in letting you retrieve data based on certain specified conditions.
In this session we'll look at the SQL Comparison Operators.
+--------+------------------+
| f_name | l_name |
+----------+----------------+
| John | Hagan |
| John | MacFarland |
+----------+----------------+
2 rows in set (0.00 sec)
This displays the first and last names of all employees whose first names are John. Note that the word
John in the condition is surrounded by single quotes. You can also use double quotes. The quotes are
important since MySQL will throw an error if they are missing. Also, MySQL comparisons are case
insensitive; which means "john", "John" or even "John" would work!
+-----------+---------------+
| f_name | l_name |
+----------+----------------+
| Fred | Kruger |
| John | MacFarland |
| Edward | Sakamuro |
| Alok | Nanda |
+----------+-----------------+
4 rows in set (0.00 sec)
Selects the first and last names of all employees who are programmers.
This lists the first and last names of all employees 32 years of age. Remember that the field data type of
age was int, hence it's not necessary to surround 32 with quotes. This is a subtle difference between text
and integer field types.
The != means 'not equal to' and is the opposite of the equality operator.
select f_name, l_name, age, salary from employee_data where age >= 33;
+---------+---------------+------+---------+
| f_name | l_name | age | salary |
+---------+---------------+------+---------+
| John | MacFarland | 34 | 80000 |
| Hassan | Rajabi | 33 | 90000 |
| Paul | Simon | 43 | 85000 |
| Roger | Lewis | 35 | 100000 |
| Danny | Gibson | 34 | 90000 |
| Mike | Harper | 36 | 120000 |
| Peter | Champion | 36 | 120000 |
+--------+----------------+------+----------+
7 rows in set (0.00 sec)
Selects the names, ages and salaries of employees who are more than or equal to 33 years of age..
Displays employee names who have less than or equal to 2 years of service in the company.
2
1. Write the SELECT statement to extract the ids of employees who are more than 30 years of age.
2. Write the SELECT statement to extract the first and last names of all web designers.
3. What will the following SELECT statement display:
SELECT * from employee_data where salary <=100000;
4. How will you display the salaries and perks for employees who have more than $16000 as perks?
5. List all employee names (last name followed by first name) who hold the title of Marketing
Executive.
Pattern Matching with text data
We will now learn at how to match text patterns using the where clause and the LIKE operator in this
section of the MySQL manual.
The equal to(=) comparison operator helps is selecting strings that are identical. Thus, to list the names
of employees whose first names are John, we can use the following SELECT statement.
+--------+------------ -+
| f_name | l_name |
+---------+--------------+
| John | Hagan |
| John | MacFarland |
+--------+--------------+
2 rows in set (0.00 sec)
What if we wanted to display employees whose first names begin with the alphabet J?
SQL allows for some pattern matching with string data. Here is how it works.
+--------+---------------+
| f_name | l_name |
+-------- +--------------+
| John | Hagan |
| John | MacFarland |
| Joseph | Irvine |
+-------- +--------------+
3 rows in set (0.00 sec)
You'll notice that we've replaced the Equal To sign with LIKE and we've used a percentage sign (%) in
the condition.
The % sign functions as a wildcard (similar to the usage of * in DOS and Linux systems). It signifies
any character. Thus, "J%" means all strings that begin with the alphabet J.
Similarly "%S" selects strings that end with S and "%H%", strings that contain the alphabet H.
Okay, let's list all the employees that have Senior in their titles.
Listing all employees whose last names end with A is very simple
+-------- +----------+
| f_name | l_name |
+-------- +----------+
| Manish | Sharma |
| Alok | Nanda |
| Arthur | Hoopla |
+--------+----------+
3 rows in set (0.00 sec)
3
1. List all employees whose last names begin with P.
2. Display the names of all employees in the marketing division.
3. What will the following statement display
SELECT f_name, l_name, salary from
employee_data where f_name like '%k%';
4. List the last names and titles of all programmers
Logical Operators
In this section of the SQL primer we look at how to select data based on certain conditions presented
through MySQL logical operators.
SQL conditions can also contain Boolean (logical) operators. They are
1). AND
2). OR
3). NOT
Their usage is quite simple. Here is a SELECT statement that lists the names of employees who draw
more than $70000 but less than $90000.
+--------+------------------+
| f_name | l_name |
+--------+-------------------+
| Mary | Anchor |
| Fred | Kruger |
| John | MacFarland |
| Edward | Sakamuro |
| Paul | Simon |
| Arthur | Hoopla |
| Joseph | Irvine |
+--------+------------------+
7 rows in set (0.00 sec)
Let's display the last names of employees whose last names start with the alphabet S or A.
+--------+--------------+------+
| f_name | l_name | age |
+---------+-------------+------+
| Manish | Sharma | 28 |
| Mary | Anchor | 26 |
| Edward | Sakamuro | 25 |
| Hal | Simlai | 27 |
+--------+-------------+------+
4 rows in set (0.00 sec)
Note the usage of parenthesis in the statement above. The parenthesis are meant to separate the various
logical conditions and remove any ambiguity.
The NOT operator helps in listing all non programmers. (Programmers include Senior programmers,
Multimedia Programmers and Programmers).
+------------+----------+-----------------------------------+
| f_name | l_name | title |
+-----------+-----------+------------------------------------+
| Manish | Sharma | CEO |
| Anamika | Pandit | Web Designer |
| Mary | Anchor | Web Designer |
| Kim | Hunter | Senior Web Designer |
| Roger | Lewis | System Administrator |
| Danny | Gibson | System Administrator |
| Mike | Harper | Senior Marketing Executive |
| Monica | Sehgal | Marketing Executive |
| Hal | Simlai | Marketing Executive |
| Joseph | Irvine | Marketing Executive |
| Shahida | Ali | Customer Service Manager |
| Peter | Champion | Finance Manager |
+---------+--------------+----------------------------------+
12 rows in set (0.00 sec)
4
1. List the first and last names of all employees who draw less than or equal to $90000 and are not
Programmes, Senior programmers or Multimedia programmers.
2. What is displayed by the following statement?
SELECT l_name, f_name from employee_data
where title NOT LIKE '%marketing%'
AND age < 30;
3. List all ids and names of all employees between 32 and 40 years of age.
4. Select names of all employees who are 32 years of age and are not programmers.
MySQL - IN and BETWEEN
This section of the manual MySQL looks at the In and BETWEEN operators.
To list employees who are Web Designers and System Administrators, we use a SELECT statement as
SELECT f_name, l_name, title from
-> employee_data where
-> title = 'Web Designer' OR
-> title = 'System Administrator';
+---------+--------+----------------------+
| f_name | l_name | title |
+---------+--------+----------------------+
| Anamika | Pandit | Web Designer |
| Mary | Anchor | Web Designer |
| Roger | Lewis | System Administrator |
| Danny | Gibson | System Administrator |
+---------+--------+----------------------+
4 rows in set (0.01 sec)
SQL also provides an easier method with IN. Its usage is quite simple.
SELECT f_name, l_name, title from
-> employee_data where title
-> IN ('Web Designer', 'System Administrator');
+---------+--------+----------------------+
| f_name | l_name | title |
+---------+--------+----------------------+
| Anamika | Pandit | Web Designer |
| Mary | Anchor | Web Designer |
| Roger | Lewis | System Administrator |
| Danny | Gibson | System Administrator |
+---------+--------+----------------------+
4 rows in set (0.00 sec)
Suffixing NOT to IN will display data that is NOT found IN the condition. The following lists
employees who hold titles other than Programmer and Marketing Executive.
+---------+----------+----------------------------+
| f_name | l_name | title |
+---------+----------+----------------------------+
| Manish | Sharma | CEO |
| John | Hagan | Senior Programmer |
| Ganesh | Pillai | Senior Programmer |
| Anamika | Pandit | Web Designer |
| Mary | Anchor | Web Designer |
| Hassan | Rajabi | Multimedia Programmer |
| Paul | Simon | Multimedia Programmer |
| Arthur | Hoopla | Multimedia Programmer |
| Kim | Hunter | Senior Web Designer |
| Roger | Lewis | System Administrator |
| Danny | Gibson | System Administrator |
| Mike | Harper | Senior Marketing Executive |
| Shahida | Ali | Customer Service Manager |
| Peter | Champion | Finance Manager |
+---------+----------+----------------------------+
14 rows in set (0.00 sec)
BETWEEN is employed to specify integer ranges. Thus instead of age >= 32 AND age <= 40, we can
use age BETWEEN 32 and 40.
select f_name, l_name, age from
-> employee_data where age BETWEEN
-> 32 AND 40;
+---------+------------+------+
| f_name | l_name | age |
+---------+------------+------+
| John | Hagan | 32 |
| Ganesh | Pillai | 32 |
| John | MacFarland | 34 |
| Alok | Nanda | 32 |
| Hassan | Rajabi | 33 |
| Arthur | Hoopla | 32 |
| Kim | Hunter | 32 |
| Roger | Lewis | 35 |
| Danny | Gibson | 34 |
| Mike | Harper | 36 |
| Shahida | Ali | 32 |
| Peter | Champion | 36 |
+---------+------------+------+
12 rows in set (0.00 sec)
You can use NOT with BETWEEN as in the following statement that lists employees who draw
salaries less than $90000 and more than $150000.
select f_name, l_name, salary
-> from employee_data where salary
-> NOT BETWEEN
-> 90000 AND 150000;
+---------+------------+--------+
| f_name | l_name | salary |
+---------+------------+--------+
| Manish | Sharma | 200000 |
| Mary | Anchor | 85000 |
| Fred | Kruger | 75000 |
| John | MacFarland | 80000 |
| Edward | Sakamuro | 75000 |
| Alok | Nanda | 70000 |
| Paul | Simon | 85000 |
| Arthur | Hoopla | 75000 |
| Hal | Simlai | 70000 |
| Joseph | Irvine | 72000 |
| Shahida | Ali | 70000 |
+---------+------------+--------+
11 rows in set (0.00 sec)
5
1. List all employees who hold the titles of "Senior Programmer" and "Multimedia Programmer".
2. List all employee names with salaries for employees who draw between $70000 and $90000.
3. What will the following statement display?
Ordering data
This section of the MySQL manual looks at how we can change the display order of the data extracted
from MySQL tables using the ORDER BY clause of the SELECT statement.
The data that we have retrieved so far was always displayed in the order in which it was stored in the
table. Actually, SQL allows for sorting of retrieved data with the ORDER BY clause. This clause
requires the column name based on which the data will be sorted. Let's see how to display employee
names with last names sorted alphabetically (in ascending order).
SELECT l_name, f_name from employee_data ORDER BY l_name;
+------------+---------+
| l_name | f_name |
+------------+---------+
| Ali | Shahida |
| Anchor | Mary |
| Champion | Peter |
| Gibson | Danny |
| Hagan | John |
| Harper | Mike |
| Hoopla | Arthur |
| Hunter | Kim |
| Irvine | Joseph |
| Kruger | Fred |
| Lewis | Roger |
| MacFarland | John |
| Nanda | Alok |
| Pandit | Anamika |
| Pillai | Ganesh |
| Rajabi | Hassan |
| Sakamuro | Edward |
| Sehgal | Monica |
| Sharma | Manish |
| Simlai | Hal |
| Simon | Paul |
+------------+---------+
21 rows in set (0.00 sec)
The ORDER BY clause can sort in an ASCENDING (ASC) or DESCENDING (DESC) order depending
upon the argument supplied.
To list employee first names in descending order, we'll use the statement below.
SELECT f_name from employee_data
ORDER by f_name DESC;
+---------+
| f_name |
+---------+
| Shahida |
| Roger |
| Peter |
| Paul |
| Monica |
| Mike |
| Mary |
| Manish |
| Kim |
| Joseph |
| John |
| John |
| Hassan |
| Hal |
| Ganesh |
| Fred |
| Edward |
| Danny |
| Arthur |
| Anamika |
| Alok |
+---------+
21 rows in set (0.00 sec)
6
1. Order all employees on the basis of the salary they draw.
2. List all employees in descending order of their years of service.
3. What does the following statement display?
Extracting Subsets
Limit can also be used to extract a subset of data by providing an additional argument.
The general form of this LIMIT is:
SELECT (whatever) from table LIMIT starting row, Number to extract;
SELECT f_name, l_name from employee_data LIMIT 6,3;
+--------+------------+
| f_name | l_name |
+--------+------------+
| John | MacFarland |
| Edward | Sakamuro |
| Alok | Nanda |
+--------+------------+
3 rows in set (0.00 sec)
This extracts 3 rows starting from the sixth row.
7
1. List the names of 5 youngest employees in the company.
2. Extract the next 5 entries starting with the 10 row.
3. Display the names and salary of the employee who draws the largest salary.
You'll notice that the display contains multiple occurrences of certain data. The SQL DISTINCT clause
lists only unique data. Here is how you use it.
select DISTINCT title from employee_data;
+----------------------------+
| title |
+----------------------------+
| CEO |
| Customer Service Manager |
| Finance Manager |
| Marketing Executive |
| Multimedia Programmer |
| Programmer |
| Senior Market ing Executive |
| Senior Programmer |
| Senior Web Designer |
| System Administrator |
| Web Designer |
+-------------- --------------+
11 rows in set (0.00 sec)
This shows we have 11 unique titles in the company.
Also, you can sort the unique entries using ORDER BY.
select DISTINCT age from employee_data
ORDER BY age;
+------+
| age |
+------+
| 25 |
| 26 |
| 27 |
| 28 |
| 30 |
| 31 |
| 32 |
| 33 |
| 34 |
| 35 |
| 36 |
| 43 |
+------+
12 rows in set (0.00 sec)
8
1. How many unique salary packages does our company, Bignet, offer? List them is descending
order.
2. How many distinct first names do we have in our database?
Finding the minimum and maximum values
MySQL provides inbuilt functions to find the minimum and maximum values.
SQL provides 5 aggregate functions. They are:
1). MIN(): Minimum value
2). MAX(): Maximum value
3). SUM(): The sum of values
4). AVG(): The average values
5). COUNT(): Counts the number of entries.
Minimum value
select MIN(salary) from employee_data;
+-------------+
| MIN(salary) |
+-------------+
| 70000 |
+-------------+
1 row in set (0.00 sec)
Maximum value
select MAX(salary) from employee_data;
+-------------+
| MAX(salary) |
+-------------+
| 200000 |
+-------------+
1 row in set (0.00 sec)
9
1. List the minimum perks package.
2. List the maximum salary given to a "Programmer".
3. Display the age of the oldest "Marketing Executive".
4. (Tricky!) Find the first and last names of the oldest employee.
Finding the average and sum
Totalling column values with SUM
The SUM() aggregate function calculates the total of values in a column. You require to give the column
name, which should be placed inside parenthesis.
Let's see how much Bignet spends on salaries.
+-------------+
| SUM(salary) |
+-------------+
| 1997000 |
+-------------+
1 row in set (0.00 sec)
+------------+
| SUM(perks) |
+------------+
| 390000 |
+------------+
1 row in set (0.00 sec)
+-------------------------+
| sum(salary)+ sum(perks) |
+-------------------------+
| 2387000 |
+-------------------------+
1 row in set (0.01 sec)
This shows a hidden gem of the SELECT command. You can add, subtract, multiply or divide values.
Actually, you can write full blown arithemetic expressions. Cool!
Finding Averages
The AVG() aggregate function is employed for calculating averages of data in columns.
select avg(age) from employee_data;
+----------+
| avg(age) |
+----------+
| 31.6190 |
+----------+
1 row in set (0.00 sec)
This displays the average age of employees in Bignet and the following displays the average salary.
select avg(salary) from employee_data;
+-------------+
| avg(salary) |
+-------------+
| 95095.2381 |
+-------------+
1 row in set (0.00 sec)
10
1. Display the sum of ages of employees working at Bignet.
2. How would you calculate the total of years of service the employees of Bignet have in the company?
3. Calculate the sum of salaries and the average age of employees who hold "Programmer" title.
Naming Columns
MySQL allows you to name the displayed columns. So instead of f_name or l_name etc. you can use
more descriptive terms. This is achieved with AS.
select avg(salary) AS
'Average Salary' from
employee_data;
+----------------+
| Average Salary |
+----------------+
| 95095.2381 |
+----------------+
1 row in set (0.00 sec)
Such pseudo names make will the display more clear to users. The important thing to remember here is
that if you assign pseudo names that contain spaces, enclose the names in quotes. Here is another
example:
select (SUM(perks)/SUM(salary) * 100)
AS 'Perk Percentage' from
employee_data;
+-----------------+
| Perk Percentage |
+-----------------+
| 19.53 |
+-----------------+
1 row in set (0.00 sec)
Counting
The COUNT() aggregate functions counts and displays the total number of entries. For example, to
count the total number of entries in the table, issue the command below.
select COUNT(*) from employee_data;
+----------+
| COUNT(*) |
+----------+
| 21 |
+----------+
1 row in set (0.00 sec)
As you have learnt, the * sign means "all data"
Now, let's count the total number of employees who hold the "Programmer" title.
select COUNT(*) from employee_data
where title = 'Programmer';
+----------+
| COUNT(*) |
+----------+
| 4 |
+----------+
1 row in set (0.01 sec)
+----------------------------+
| title |
+----------------------------+
| CEO |
| Customer Service Manager |
| Finance Manager |
| Marketing Executive |
| Multimedia Programmer |
| Programmer |
| Senior Marketing Executive |
| Senior Programmer |
| Senior Web Designer |
| System Administrator |
| Web Designer |
+----------------------------+
11 rows in set (0.01 sec)
You'll notice that this is similar to the usage of DISTINCT, which we encountered in a previous session.
Okay, here is how you can count the number of employees with different titles.
select title, count(*)
from employee_data GROUP BY title;
+----------------------------+----------+
| title | count(*) |
+----------------------------+----------+
| CEO | 1 |
| Customer Service Manager | 1 |
| Finance Manager | 1 |
| Marketing Executive | 3 |
| Multimedia Programmer | 3 |
| Programmer | 4 |
| Senior Marketing Executive | 1 |
| Senior Programmer | 2 |
| Senior Web Designer | 1 |
| System Administrator | 2 |
| Web Designer | 2 |
+----------------------------+----------+
11 rows in set (0.00 sec)
For the command above, MySQL first groups different titles and then executes count on each group.
Sorting the data
Now, let's find and list the number of employees holding different titles and sort them using ORDER
BY.
select title, count(*) AS Number
from employee_data
GROUP BY title
ORDER BY Number;
+----------------------------+--------+
| title | Number |
+----------------------------+--------+
| CEO | 1 |
| Customer Service Manager | 1 |
| Finance Manager | 1 |
| Senior Marketing Executive | 1 |
| Senior Web Designer | 1 |
| Senior Programmer | 2 |
| System Administrator | 2 |
| Web Designer | 2 |
| Marketing Executive | 3 |
| Multimedia Programmer | 3 |
| Programmer | 4 |
+----------------------------+--------+
11 rows in set (0.00 sec)
11
1. Count the number of employees who have been with Bignet for four or more years.
2. Count employees based on their ages.
3. Modify the above so that the ages are listed in a descending order.
4. Find the average age of employees in different departments (titles).
5. Change the above statement so that the data is displayed in a descending order of average ages.
6. Find and list the percentage perk (perk/salary X 100) for each employee with the % perks sorted in a
descending order.
HAVING clause
To list the average salary of employees in different departments (titles), we use the GROUP BY clause,
as in:
select title, AVG(salary) from employee_data
GROUP BY title;
+----------------------------+-------------+
| title | AVG(salary) |
+----------------------------+-------------+
| CEO | 200000.0000 |
| Customer Service Manager | 70000.0000 |
| Finance Manager | 120000.0000 |
| Marketing Executive | 77333.3333 |
| Multimedia Programmer | 83333.3333 |
| Programmer | 75000.0000 |
| Senior Marketing Executive | 120000.0000 |
| Senior Programmer | 115000.0000 |
| Senior Web Designer | 110000.0000 |
| System Administrator | 95000.0000 |
| Web Designer | 87500.0000 |
+----------------------------+-------------+
11 rows in set (0.00 sec)
Now, suppose you want to list only the departments where the average salary is more than
$100000, you can't do it, even if you assign a pseudo name to AVG(salary) column. Here, the HAVING
clause comes to our rescue.
select title, AVG(salary) from employee_data GROUP BY title
HAVING AVG(salary) > 100000;
+----------------------------+-------------+
| title | AVG(salary) |
+----------------------------+-------------+
| CEO | 200000.0000 |
| Finance Manager | 120000.0000 |
| Senior Marketing Executive | 120000.0000 |
| Senior Programmer | 115000.0000 |
| Senior Web Designer | 110000.0000 |
+----------------------------+-------------+
5 rows in set (0.00 sec)
12
1. List departments and average ages where the average age in more than 30.
SELECT YEAR(CURRENT_DATE);
+--------------------+
| YEAR(CURRENT_DATE) |
+--------------------+
| 2001 |
+--------------------+
1 row in set (0.00 sec)
Obviously you can provide pseudo names for these columns using AS.
select 'Manish Sharma' as Name;
+---------------+
| Name |
+---------------+
| Manish Sharma |
+---------------+
1 row in set (0.00 sec)
Evaluating expressions
select ((4 * 4) / 10 ) + 25;
+----------------------+
| ((4 * 4) / 10 ) + 25 |
+----------------------+
| 26.60 |
+----------------------+
1 row in set (0.00 sec)
Concatenating
With SELECT you can concatenate values for display. CONCAT accepts arguments between
parenthesis. These can be column names or plain text strings. Text strings have to be surrounded with
quotes (single or double).
SELECT CONCAT(f_name, " ", l_name)
from employee_data
where title = 'Programmer';
+-----------------------------+
| CONCAT(f_name, " ", l_name) |
+-----------------------------+
| Fred Kruger |
| John MacFarland |
| Edward Sakamuro |
| Alok Nanda |
+-----------------------------+
4 rows in set (0.00 sec)
You can also give descriptive names to these columns using AS.
select CONCAT(f_name, " ", l_name)
AS Name
from employee_data
where title = 'Marketing Executive';
+---------------+
| Name |
+---------------+
| Monica Sehgal |
| Hal Simlai |
| Joseph Irvine |
+---------------+
3 rows in set (0.00 sec)
13
1. Which command displays the MySQL version?
2. Use the SELECT command to evaluate 4 X 4 X 4 and name the column Cube of 4.
In addition to the four basic arithmetic operations addition (+), Subtraction (-), Multiplication (*) and
Division (/), MySQL also has the Modulo (%) operator. This calculates the remainder left after division.
select 87 % 9;
+--------+
| 87 % 9 |
+--------+
| 6 |
+--------+
1 row in set (0.00 sec)
MOD(x, y)
Displays the remainder of x divided by y, SImilar to the Modulus operator.
select MOD(37, 13);
+-------------+
| MOD(37, 13) |
+-------------+
| 11 |
+-------------+
1 row in set (0.00 sec)
ABS(x)
Calculates the Absolute value of number x. Thus, if x is negative its positive value is returned.
select ABS(-4.05022);
+---------------+
| ABS(-4.05022) |
+---------------+
| 4.05022 |
+---------------+
1 row in set (0.00 sec)
select ABS(4.05022);
+--------------+
| ABS(4.05022) |
+--------------+
| 4.05022 |
+--------------+
1 row in set (0.00 sec)
SIGN(x)
select SIGN(54.6);
+------------+
| SIGN(54.6) |
+------------+
| 1 |
+------------+
1 row in set (0.00 sec)
select SIGN(0);
+---------+
| SIGN(0) |
+---------+
| 0 |
+---------+
1 row in set (0.00 sec)
POWER(x,y)
SQRT(x)
Returns the value of x rounded to the nearest integer. ROUND can also accept an additional argument y
that will round x to y decimal places.
select ROUND(14.492);
+---------------+
| ROUND(14.492) |
+---------------+
| 14 |
+---------------+
1 row in set (0.00 sec)
select ROUND(4.5002);
+---------------+
| ROUND(4.5002) |
+---------------+
| 5 |
+---------------+
1 row in set (0.00 sec)
select ROUND(-12.773);
+----------------+
| ROUND(-12.773) |
+----------------+
| -13 |
+----------------+
1 row in set (0.00 sec)
select ROUND(7.235651, 3);
+--------------------+
| ROUND(7.235651, 3) |
+--------------------+
| 7.236 |
+--------------------+
1 row in set (0.00 sec)
FLOOR(x)
select CEILING(-62.23);
+-----------------+
| CEILING(-62.23) |
+-----------------+
| -62 |
+-----------------+
1 row in set (0.00 sec)
Updating records
The SQL UPDATE command updates the data in tables. Its format is quite simple.
UPDATE table_name SET
column_name1 = value1,
column_name2 = value2,
column_name3 = value3 ...
[WHERE conditions];
Obviously, like other SQL commands, you can type in in one line or multiple lines.
You can test this out by listing the data in the table.
select salary, perks from
employee_data WHERE
title = 'CEO';
+--------+-------+
| salary | perks |
+--------+-------+
| 220000 | 55000 |
+--------+-------+
1 row in set (0.00 sec)
Actually, you don't need to know the previous salary explicitly. You can be cheeky and use arithmetic
operators. Thus, the following statement would have done the same job without us knowing the original
data beforehand.
UPDATE employee_data SET
salary = salary + 20000,
perks = perks + 5000
WHERE title='CEO';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
Another progressive (???) step Bignet takes is changing the titles of Web Designer to Web Developer.
mysql> update employee_data SET
-> title = 'Web Developer'
-> WHERE title = 'Web Designer';
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
It's important that you take a long hard look at the condition part in the
statement before executing update, else you might update the wrong data.
Also, an UPDATE statement without conditions will update all the data in
the column in all rows!
Be very caferul.
14
1. Our CEO falls in love with the petite Web Developer, Anamika Pandit. She now wants her last name to be
changed to 'Sharma'.
2. All Multimedia Programmers now want to be called Multimedia Specialists.
3. After his marriage, the CEO gives everyone a raise. Increase the salaries of all employees (except the CEO)
by $10000.
MySQL Date column type part 1
Till now we've dealt with text (varchar) and numbers (int) data types. To understand date type, we'll
create one more table.
CREATE TABLE employee_per (e_id int unsigned not null primary key, address varchar(60), phone int,
p_email varchar(60), birth_date DATE, sex ENUM('M', 'F'), m_status ENUM('Y','N'), s_name
varchar(40), children int);
Insert records 2
View table 2
The details of the table can be displayed with DESCRIBE command.
mysql> DESCRIBE employee_per;
+------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+-------+
| e_id | int(10) unsigned | | PRI | 0 | |
| address | varchar(60) | YES | | NULL | |
| phone | int(11) | YES | | NULL | |
| p_email | varchar(60) | YES | | NULL | |
| birth_date | date | YES | | NULL | |
| sex | enum('M','F') | YES | | NULL | |
| m_status | enum('Y','N') | YES | | NULL | |
| s_name | varchar(40) | YES | | NULL | |
| children | int(11) | YES | | NULL | |
+------------+------------------+------+-----+---------+-------+
9 rows in set (0.01 sec)
Notice that column birth_date has date as column type. I've also introduced another column type
ENUM, which we'll discuss later.
e-id: are employee ids, same as that in table employee_data
address: Addresses of employees
phone: Phone numbers
p_email: Personal email addresses
birth_date: Birth dates
sex: The sex of the employee, Male or Female
m_status: Marital status,Yes or No.
s_name: Name of Spouse (NULL if employee is unmarried)
children: Number of children (NULL if employee is unmarried)
Characteristics of Date
MySQL dates are ALWAYS represented with the year followed by the month and then the date. Often
you'll find dates written as YYYY-MM-DD, where YYYY is 4 digit year, MM is 2 digit month and DD, 2
digit date. We'll look at DATE and related column types in the session on column types.
Operations on Date
Date column type allow for several operations such as sorting, testing conditions using comparision
operators etc.
Using = and != operators
select p_email, phone
from employee_per
where birth_date = '1969-12-31';
+---------------------------+---------+
| p_email | phone |
+---------------------------+---------+
| [email protected] | 6666666 |
+---------------------------+---------+
1 row in set (0.00 sec)
15
1. List all employee ids and birth dates who were born before 1965.
2. Display Ids and birth dates of employees born in and between 1970 and 1972. (This is tricky... think a little
We had seen in the session on SELECT statement that current date, month and year can be displayed
with CURRENT_DATE argument to DAYOFMONTH(), MONTH() and YEAR() clauses, respectively.
The same can be used to select data from tables.
select e_id, birth_date
from employee_per where
MONTH(birth_date) = MONTH(CURRENT_DATE);
+------+------------+
| e_id | birth_date |
+------+------------+
| 8 | 1975-01-12 |
| 19 | 1973-01-20 |
| 20 | 1968-01-25 |
+------+------------+
3 rows in set (0.00 sec)
16
1. List ids, birth dates and emails of employes born in April.
2. Display Ids, birth dates and spouse names of employees born in 1969 and sort the entires on the basis of
their spouse names.
3. List the emploee ids for employees born under the current month.
4. How many unique birth years do we have?
5. Display a list of unique birth years and the number of employees born under each.
6. How many employees were born under each month? The display should have month names (NOT numbers)
and the entries should be sorted with the month having the largest number listed first.
Null column type
The NULL column type is special in many ways. To insert a NULL value, just leave the column name
from the INSERT statement. Columns have NULL as default unless specified by NOT NULL. You can
have null values for integers as well as text or binary data.
NULL cannot be compared using arithemetic operators. Comparisions for NULL take place with IS
NULL or IS NOT NULL.
select e_id, children
from employee_per
where children IS NOT NULL;
+------+----------+
| e_id | children |
+------+----------+
| 2 | 3 |
| 3 | 2 |
| 7 | 3 |
| 9 | 1 |
| 11 | 4 |
| 12 | 3 |
| 13 | 2 |
| 15 | 3 |
| 16 | 2 |
| 17 | 1 |
| 21 | 2 |
+------+----------+
11 rows in set (0.00 sec)
The above lists ids and no. of children of all employees who have children.
17
1. Find and list the ids and spouse names of all employees who are married.
2. Change the above so that the display is sorted on spouse names.
3. How many employees do we have under each sex (male and female)?
4. How many of our employees are married and unmarried?
5. Find the total number of children.
6. Make unique groups of children and find the number in each group. Sort the display with the group having
maximum children, at the top.
+-----------------+-----------------+
| Name | Spouse Name |
+-----------------+-----------------+
| Manish Sharma | Anamika Sharma |
| John Hagan | Jane Donner |
| Ganesh Pillai | Sandhya Pillai |
| Anamika Sharma | Manish Sharma |
| John MacFarland | Mary Shelly |
| Alok Nanda | Manika Nanda |
| Paul Simon | Muriel Lovelace |
| Arthur Hoopla | Rina Brighton |
| Kim Hunter | Matt Shikari |
| Danny Gibson | Betty Cudly |
| Mike Harper | Stella Stevens |
| Monica Sehgal | Edgar Alan |
| Peter Champion | Ruby Richer |
+-----------------+-----------------+
13 rows in set (0.00 sec)
The FROM clause takes the names of the two tables from which we plan to extract data. Also, we
specify that data has to be retrieved for only those entries where the emp_id and e_id are same.
The names of columns in the two tables are unique. However, this may not true always, in which case
we can explicitly specify column names along with table name using the dot notation.
select CONCAT(employee_data.f_name, " ", employee_data.l_name)
AS Name, employee_per.s_name AS 'Spouse Name'
from employee_data, employee_per
where employee_per.m_status = 'Y'
AND employee_data.emp_id = employee_per.e_id;
+-----------------+-----------------+
| Name | Spouse Name |
+-----------------+-----------------+
| Manish Sharma | Anamika Sharma |
| John Hagan | Jane Donner |
| Ganesh Pillai | Sandhya Pillai |
| Anamika Sharma | Manish Sharma |
| John MacFarland | Mary Shelly |
| Alok Nanda | Manika Nanda |
| Paul Simon | Muriel Lovelace |
| Arthur Hoopla | Rina Brighton |
| Kim Hunter | Matt Shikari |
| Danny Gibson | Betty Cudly |
| Mike Harper | Stella Stevens |
| Monica Sehgal | Edgar Alan |
| Peter Champion | Ruby Richer |
+-----------------+-----------------+
13 rows in set (0.00 sec)
Dropping tables
To remove all entries from the table we can issue the DELETE statement without any conditions.
DELETE from employee_data;
Query OK, 0 rows affected (0.00 sec)
However, this does not delete the table. The table still remains, which you can check with SHOW
TABLES;
mysql> SHOW TABLES;
+---------------------+
| Tables in employees |
+---------------------+
| employee_data |
+---------------------+
1 rows in set (0.00 sec)