Professional Documents
Culture Documents
relational databases
5
Using
a
Database
To
get
started
with
you
own
database,
first
check
which
databases
currently
exist
on
the
server.
6
Using
a
database
• To
delete
and
create
a
database:
mysql> DROP DATABASE IF EXISTS employees;
mysql> create database employees;
7
Creating
a
Table
• Once
you
have
selected
a
database,
you
can
view
all
database
tables:
mysql> show tables;
Empty set (0.02 sec)
8
Let’s
create
the
EMPLOYEE
table
mysql> CREATE TABLE employee (
-> empid INT AUTO_INCREMENT,
-> firstname VARCHAR(30),
-> lastname VARCHAR(20),
-> deptcode CHAR(6),
-> salary NUMERIC(9, 2),
-> PRIMARY KEY(empid)
-> );
10
Describing
Tables
To
see
the
structure
of
a
table,
use
the
DESCRIBE
command
(or
desc):
11
Deleting
a
table
To
delete
an
entire
table,
use
the
DROP
TABLE
command:
mysql> drop table employee;
Query OK, 0 rows affected (0.02
sec)
12
Let’s
create
again
the
EMPLOYEE
table
and
let’s
create
the
DEPARTMENT
+-----------+
table
| Employee |
+-----------+
CREATE TABLE employee (
| empid |
empid INT AUTO_INCREMENT,
| firstname |
firstname VARCHAR(30),
| lastname |
lastname VARCHAR(20),
| deptcode |
deptcode CHAR(6),
| salary |
salary NUMERIC(9, 2),
+-----------+
PRIMARY KEY(empid));
+------------+
CREATE TABLE department ( | Department |
code CHAR(6), +------------+
| code |
name VARCHAR(30), | name |
managerid INT, | managerid# |
subdeptof CHAR(6), | subdeptof# |
PRIMARY KEY(code), +------------+
FOREIGN KEY(managerid) REFERENCES employee(empid),
FOREIGN KEY(subdeptof) REFERENCES department(code)
);
Let’s
create
again
the
EMPLOYEE
table
and
let’s
create
the
DEPARTMENT
table
CREATE TABLE employee (
empid INT AUTO_INCREMENT, But
...
in
a
department
firstname VARCHAR(30), there
are
several
lastname VARCHAR(20), employers
and,
usually,
deptcode CHAR(6), each
employee
belongs
to
salary NUMERIC(9, 2), a
department!
PRIMARY KEY(empid));
+------------+
| Department |
+------------+
| code |
| name |
| managerid# |
| subdeptof# |
+------------+
21
Now is your turn!
QCM 1.1
TP 1.1
22
1.2
Select
statement
23
Format
of
an
SQL
Select
General
syntax: Simplified syntax :
E.g.:
SELECT * FROM department;
SELECT firstname, lastname
FROM employee
WHERE deptcode='consul';
24
Basic
queries
Once
you
are
logged
in,
you
can
try
some
simple
queries.
For
example:
mysql> SELECT VERSION(), CURRENT_DATE;
+-----------+--------------+
| VERSION() | CURRENT_DATE |
+-----------+--------------+
| 5.6.25 | 2016-01-13 |
+-----------+--------------+
1 row in set (0.01 sec)
25
Basic
queries
Here
is
another
query.
It
demonstrates
that
you
can
use
MySQL
as
a
simple
calculator:
26
Basic
Queries
Semicolons
(multiple
statements
on
a
single
line) VS.
comas
(multiple
columns
in
a
single
line):
27
Multi-‐line
commands
MySQL
determines
where
your
statement
ends
by
looking
for
the
terminating
semicolon,
not
by
looking
for
the
end
of
the
input
line.
mysql> SELECT
-> USER()
-> ,
-> CURRENT_DATE;
+----------------+--------------+
| user() | current_date |
+----------------+--------------+
| root@localhost | 2016-01-13 |
+----------------+--------------+
28
Canceling
a
command
If
you
decide
you
don't
want
to
execute
a
command
that
you
are
in
the
process
of
entering,
cancel
it
by
typing
\c
mysql> SELECT
-> USER()
-> \c
mysql>
29
+-----------+
30
+-----------+
Example 3 | Employee |
+-----------+
| empid |
| firstname |
Select
the
first
name,
last
name
and
salary
of
| lastname |
the
employees
who
belong
to
the
consulting
| deptcode# |
department
and
they
earn
more
than
50.000
a
| salary |
year
(then
calculate
the
monthly
salary). +-----------+
+------------+
Select firstname, lastname, salary
| Department |
from employee e, department d +------------+
where e.deptcode=d.code and | code |
d.name='consulting' and salary > 50000; | name |
| managerid# |
Select salary/12 'salaire mensuel' | subdeptof# |
from employee e, department d +------------+
where e.deptcode=d.code and
d.name='consulting' and salary > 50000;
Example 4 | Employee |
+-----------+
| empid |
| firstname |
Calculate
the
total
of
wages
paid
to
employees
| lastname |
by
department (ORDER
BY
code). | deptcode# |
| salary |
Select d.code, sum(salary) +-----------+
from employee e, department d
+------------+
where e.deptcode=d.code
| Department |
group by d.code; +------------+
| code |
You
can use
Order by
…
DESC
or
ASC
after group
by,
| name |
for
example: | managerid# |
| subdeptof# |
Select d.code, sum(salary) +------------+
from employee e, department d
where e.deptcode=d.code
group by d.code
order by d.code DESC;
32
+-----------+
Example 5
| Employee |
+-----------+
| empid |
| firstname |
Build
the
list
of
salaries
by
department. | lastname |
| deptcode# |
SELECT deptcode, salary | salary |
FROM employee e, department d +-----------+
WHERE d.code=e.deptcode +------------+
GROUP BY deptcode; | Department |
+------------+
| code |
| name |
ERROR
1055
(42000):
Expression
#2
of
SELECT
| managerid# |
list
is
not
in
GROUP
BY
clause
and
contains
| subdeptof# |
nonaggregated column
'employees.e.salary'
+------------+
Example 5
| Employee |
+-----------+
| empid |
| firstname |
Build
the
list
of
salaries
by
department. | lastname |
| deptcode# |
SELECT deptcode, salary | salary |
FROM employee e, department d +-----------+
WHERE d.code=e.deptcode +------------+
GROUP BY deptcode; | Department |
+------------+
According
to
the
documentation,
this
configuration
is
| code |
| name |
being
enabled
by
default
from
MySQL
5.7.5
because
| managerid# |
GROUP
BY
processing
has
become
more
sophisticated
| subdeptof# |
to
include
detection
of
functional
dependencies
+------------+
(salary
is
not
functionally
dependent
on
deptcode).
It
also
brings
MySQL
closer
to
the
best
practices
for
SQL
language
with
the
bonus
of
removing
the
“magic”
element
when
grouping.
Having
that,
grouping
fields
are
no
longer
arbitrary
selected. 34
Example 5
If
you
are
upgrading
your
database
server
and
want
to
avoid
any
possible
breaks
you
can
disable
by
disabling
ONLY_FULL_GROUP_BY
from
your
sql_mode.
SET
@@GLOBAL.sql_mode =
'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZER
O,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
A
restart
is
not
necessary,
but
a
reconnection
is.
Change permanently
If you want to disable it permanently, add/edit the following in your my.cnf file:
sql_mode =
"STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZER
O,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
For
this
change
a
service
restart
is
required
Example 5
| Employee |
+-----------+
| empid |
| firstname |
Build
the
list
of
salaries
by
department. | lastname |
| deptcode# |
Connect
again
to
MySQL,
charge
the
database
| salary |
and
execute
the
request
again: +-----------+
+------------+
SELECT deptcode, salary | Department |
FROM employee e, department d +------------+
WHERE d.code=e.deptcode | code |
| name |
GROUP BY deptcode; | managerid# |
+----------+----------+ | subdeptof# |
| deptcode | salary | +------------+
+----------+----------+
| ADMIN | 70000.00 |
| COMPTA | 40000.00 |
| CONSUL | 60000.00 |
| SINF | 50000.00 |
+----------+----------+ 36
+-----------+
Exemple
6 | Employee |
+-----------+
| empid |
List
the
employees
without
any
department. | firstname |
| lastname |
In
order to
do
that,
you need to: | deptcode# |
1. List
all
employees
who
have
been
registered
| salary |
at
least
once
in
a
department
(inner
query). +-----------+
2. Then,
select
the
employees
who
are
not
in
+------------+
the
list
provided
by
the
inner
query. | Department |
+------------+
select * from employee | code |
| name |
where empid not in | managerid# |
(select e.empid | subdeptof# |
from employee e, department d +------------+
where e.deptcode=d.code);
But
there
are
other
requests
somewhat
more
difficult
to
express
in
SQL,
for
example
when
it
comes
to
finding
the
elements
that
have
ALWAYS
...
37
+-----------+
Exemple
7 | Employee |
+-----------+
| empid |
Queries
to
find
elements
that
have
(always or
taken
| firstname |
every)
… | lastname |
You
have
to
implement a
division
(relational algebra)! | deptcode# |
| salary |
The
division
can
express
universal
quantification
(∀). +-----------+
Example
of
a
query
for
which
the
division
is
useful:
+------------+
"List
the
employees
who
are
hired
in
all
departments" |+------------+
Department |
| code |
select * from employee | name |
| managerid# |
where empid not exists | subdeptof# |
(select e.empid +------------+
from employee e, department d
where e.deptcode=d.code);
Here
(next
slide)
is
a
more
complex
example
in
a
database
in
which
it
is
possible
to
add
constraints
to
the
division
: 38
Division query
Student (Id, Name)
Course (CrsCode, Dept)
Transcript (StudId, CrsCode, Grade)
Query: Find the names of students who have taken every
course offered by the CS department.
Result Adam
39
Division query in SQL
Student (Id, Name)
Course (CrsCode, CrsName, Dept)
Transcript (StudId, CrsCode, Semester, Grade)
40
Division Query in SQL
Student (Id, Name)
Course (CrsCode, CrsName, Dept)
Transcript (StudId, CrsCode, Semester, Grade)
42
Division Query in SQL
Student (Id, Name)
Course (CrsCode, CrsName, Dept)
Transcript (StudId, CrsCode, Semester, Grade)
43
Division Query in SQL
Student (Id, Name)
Course (CrsCode, CrsName, Dept)
Transcript (StudId, CrsCode, Semester, Grade)
44
Division Query in SQL
Student (Id, Name)
Course (CrsCode, CrsName, Dept)
Transcript (StudId, CrsCode, Semester, Grade)
46
Another possible solution
Student (Id, Name)
Course (CrsCode, CrsName, Dept)
Transcript (StudId, CrsCode, Semester, Grade)
Exercise
8:
Retrieve
the
first
and
last
names
of
employees
in
department
'CONSUL'
whose
salary
is
between
€30,000
and
€40,000.
SELECT Fname, Lname
FROM EMPLOYEE
WHERE (Salary BETWEEN 30000 AND 40000) AND deptcode = 'CONSUL';
48
String
comparison functions
• The
keyword
LIKE
is
used
to
compare
two
strings
(case
insensitive).
• Character '%' is special and
means:
0
or
several characters.
• Character '_' is special and
means:
only 1
seul
character,
whatever it is.
To
go
forward…
Think and
implement an
example for
each function!
50
String
functions
Fonction Description
TRIM(x) Removes spaces at the beginning and end of a string
LOWER(x) Converts to lowercase
UPPER(x) Converts to uppercase
LONGUEUR(x) Returns the size of the chain
LOCATE(x,y) Returns the position of the last occurrence of x in y.
Returns 0 if x is not found in y
CONCAT(x,y,…) Concatenates the arguments
SUBSTRING(s,i,n) Returns the last n characters of s starting from the
position i
SOUNDEX(x) Returns a phonetic representation of x
To
go
forward…
Think and
implement an
example for
each function!
51
Date
and
time
functions
Fonction Description
NOW() Returns the current date and time.
TO_DAYS(x) Return the date converted to days since 1st
January 1970
DAYOFWEEK(x) Returns the day of the week of the X date.
Index starting by 1 (1=Sunday, 2=Monday…)
DAYOFMONTH(x) Returns the day of month (from 1 to 31)
DAYOFYEAR(x) Returns the day of year (from 1 to 366)
SECOND(x), MINUTE(x), Returns seconds, minutes, hours, month, year
HOUR(x), MONTH(x), and week date.
YEAR(x), WEEK(x)
To
go
forward…
Think and
implement an
example for
each function!
52
Functions
to
use
in
the
GROUP
BY
Fonction Description
COUNT([DISTINCT]x,y,…) Count of tuples of the result by projecting on
the specified attribute(s) (or all with '*'). The
DISTINCT option eliminates duplication.
MIN(x), MAX(x), AVG(x), Respectively calculates the minimum,
SUM(x) maximum, average and sum of X attribute
values.
To
go
forward…
Think and
implement an
example for
each function!
53
Regular
Expression
Matching
• The
other
type
of
pattern
matching
provided
by
MySQL
uses
extended
regular
expressions.
54
Regular
Expressions
Some
characteristics
of
extended
regular
expressions:
*
matches
zero
or
more
instances
of
the
thing
preceding
it.
For
example,
x*
matches
any
number
of
x
characters,
[0-‐9]*
matches
any
number
of
digits,
and
.*
matches
any
number
of
anything.
To
anchor
a
pattern
so
that
it
must
match
the
beginning
or
end
of
the
value
being
tested,
use
^
at
the
beginning
or
$
at
the
end
of
the
pattern.
55
+-----------+
| Employee |
Example
9 +-----------+
| empid |
| firstname |
| lastname |
To
find
names
(firstnames)
beginning
with
R,
use
^ | deptcode# |
| salary |
+-----------+
mysql> SELECT * FROM employee
WHERE firstname REGEXP '^r';
+------------+
| Department |
+-------+-----------+----------+----------+----------+ +------------+
| empid | firstname | lastname | deptcode | salary | | code |
+-------+-----------+----------+----------+----------+ | name |
| 1 | Raul | Mazo | ADMIN | 70000.00 | | managerid# |
+-------+-----------+----------+----------+----------+ | subdeptof# |
1 row in set (0.00 sec)
+------------+
56
+-----------+
Example 10 | Employee |
+-----------+
| empid |
Build the
list of
person(s)
earning the
highest wages. | firstname |
| lastname |
You
can think it would be:
| deptcode# |
select empid, max(salary) from employee; | salary |
+-----------+
But
if
you insert
another tuple with the
max wage (obtained),
you
see that it does not
work: +------------+
INSERT INTO employee (firstname,lastname, | Department |
deptcode, salary) VALUES ('Ivan', 'Perez', +------------+
'ADMIN', 70000); | code |
| name |
So,
use
this
syntax:
| managerid# |
select empid, firstname, salary from employee | subdeptof# |
where salary=(select max(salary) from +------------+
employee);
Example 12 | Employee |
+-----------+
| empid |
| firstname |
How
to
find
the
names
of
employees
who
are
| lastname |
not
associated
with
any
department? | deptcode# |
| salary |
There
are
several
possibilities,
for
example: +-----------+
Classify these queries from the
most to
the
least
efficient.
Why this choice?
59
Now is your turn!
QCM 1.2
TP 1.2
60