EFA8040
Data Management and
SQL
SQL, part 3
Markku Kellomäki,
[email protected]Counting with columns
Counting with columns
• You can do basic calculations with columns and change them with
functions
• You can’t use aliases in formulas
• Null in calculations results to null
• You have to prevent dividing by zero
Examples
• Count the amount of tax to be payed with salary and tax percentage
for each person:
SELECT lname, fname, salary, taxperc,
salary*taxperc/100 AS tax
FROM person;
• Like previous example, but also net salary:
SELECT lname, fname, salary, taxperc,
salary*taxperc/100 AS tax,
salary - salary*taxperc/100 AS netsalary
FROM person;
Examples
• Count the difference between hours and planned hours of projects.
Sort by difference percentage
SELECT pid, socsecno, hours, hours_planned,
COALESCE(hours_planned, 0) - hours as difference,
(COALESCE(hours_planned, 0) - hours)/hours*100 AS
diffPerc
FROM proj_pers
ORDER BY diffPerc;
Union
Union
• With UNION-query, you can combine multiple select statements
• Select statements don’t need to have logical connections
• Each select statement within union must have the same number of
columns
• The columns must also have similar data types
• UNION – shows each value only once, removes duplicates
• UNION ALL – shows duplicates
• First SELECT defines names of resulting columns, only aliases can be
defined to first select statement
Union
• Fetch all projects and persons: id’s andnames
SELECT socsecno, CONCAT(lname, fname) AS name
FROM person
UNION
SELECT pid, pname
FROM project;
Union
• Make a query, which will show where each person lives. Result will be in matrix form.
SELECT lname, fname, 'X' AS Helsinki, '' AS Tampere, '' AS Turku
FROM person
WHERE city='HELSINKI'
UNION
SELECT lname, fname, '' AS Helsinki, 'X' AS Tampere, '' AS Turku
FROM person
WHERE city='TAMPERE'
UNION
SELECT lname, fname, '' AS Helsinki, '' AS Tampere, 'X' AS Turku
FROM person
WHERE city='TURKU';
SQL joins
Joins
• With joins, you can combine two or more tables based on a related
column or columns between them
• Inner join – values of columns must be same in both tables
• Outer join – value can be missing from columns
Syntax
SELECT *
FROM tableA JOIN tableB
ON tableA.column = tableB.column;
Inner join
• If there are no condition for joining, result is cartesian product of two
tables which means that every row in table 1 is combined with every
row in table 2.
• Cartesian product is rarely usable
• Bad example: Fetch person names and names of their departments
and forget to use relation between them
SELECT *
FROM person INNER JOIN department;
• This is also called cross join
Inner join
• Example: Get all persons and their departments
SELECT fname, lname, depname
FROM person INNER JOIN department
ON person.depcode = department.depcode;
• Because there are columns that have same names, the condition
must have table defined
• You can use aliases
SELECT fname, lname, depname
FROM person p INNER JOIN department d
ON p.depcode = d.depcode;
Inner join
• Inner join is default join, so usually join is only used
SELECT fname, lname, depname
FROM person p JOIN department d
ON p.depcode = d.depcode;
• Sometimes it’s preferred to tell which table the column is on. It’s
mandatory if there columns have same names with different content.
SELECT p.fname, p.lname, d.depname
FROM person p INNER JOIN department d
ON p.depcode = d.depcode;
Inner join
• Example: Fetch names of persons, project id’s and done hours in
projects
SELECT p.fname, p.lname, pr.pid, pr.hours
FROM person p INNER JOIN proj_pers pr
ON p.socsecno = pr.socsecno;
• The same ordered by name and column
SELECT p.fname, p.lname, pr.pid, pr.hours
FROM person p inner join proj_pers pr
ON p.socsecno = pr.socsecno
ORDER BY p.lname, p.fname, pr.pid;
Inner join
• Example: Fetch names of projects and social security numbers of
persons with hours(Result should not have projects P5 and P6 as
there are no relations to those projects)
SELECT p.pname, pr.socsecno, pr.hours,
pr.hours_planned
FROM project p JOIN proj_pers pr
ON p.pid = pr.pid;
• If you want all the projects, use outer join
SELECT p.pname, pr.socsecno, pr.hours,
pr.hours_planned
FROM project p LEFT OUTER JOIN proj_pers pr
ON p.pid = pr.pid;
Inner join
• You can use multiple joins
• Example: Fetch names of projects, id’s of projects, persons names and
inputted hours
SELECT pr.pid, pr.pname, p.lname, p.fname,
pp.hours
FROM person p JOIN proj_pers pp
ON p.socsecno = pp.socsecno
JOIN project pr
ON pr.pid = pp.pid
ORDER BY pr.pid, p.lname, p.fname;
Inner join
• Example: Fetch the names of projects, project id’s, person names,
inputted hours and department names
SELECT pr.pid, pr.pname, p.lname, p.fname, d.depname,
pp.hours
FROM person p JOIN department d
ON d.depcode = p.depcode
JOIN proj_pers pp
ON p.socsecno = pp.socsecno
JOIN project pr
ON pr.pid = pp.pid
ORDER BY pr.pid, p.lname, p.fname;
Autojoin
• You can join a table to itself using aliases
• Example: Fetch all the persons that live in the same city as Leo Meri
SELECT p2.city, p2.lname, p2.fname
FROM person p1 JOIN person p2
ON p1.city = p2.city
WHERE p1.lname = 'Meri' AND p1.fname = 'Leo';
Autojoin
• Example: Fetch all the persons that live in the same city as Leo Meri
that are not Leo Meri
SELECT p2.city, p2.lname, p2.fname
FROM person p1 JOIN person p2
ON p1.city = p2.city
WHERE p1.lname = 'Meri' AND p1.fname = 'Leo'
AND p2.lname != 'Meri' AND p2.fname != 'Leo';
Left/right (outer) join
• With outer joins, lack of missing data from column to be joined is
allowed
• Left join, left outer join
• Lack of value is allowed from left table
• Right join, right outer join
• Lack of value is allowed from right table
Left/right (outer) join
• Example: Fetch all the hours done to projects with all the projects
listed
• Why both queries result the same outcome?
SELECT p.pname, pr.socsecno, pr.hours,
pr.hours_planned
FROM project p LEFT JOIN proj_pers pr ON p.pid =
pr.pid;
SELECT p.pname, pr.socsecno, pr.hours,
pr.hours_planned
FROM proj_pers pr RIGHT JOIN project p ON p.pid =
pr.pid;
Full (outer) join
• With some databases it’s possible to use full join
• It allows missing of values from both tables