0% found this document useful (0 votes)
67 views48 pages

Advanced SQL (Part 1) Nataliya Bogushevskaya

Advanced SQL (Part 1) Nataliya Bogushevskaya

Uploaded by

juliyagorelik
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
67 views48 pages

Advanced SQL (Part 1) Nataliya Bogushevskaya

Advanced SQL (Part 1) Nataliya Bogushevskaya

Uploaded by

juliyagorelik
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 48

Advanced SQL

Nataliya Bogushevskaya

2019

CONFIDENTIAL 1
FEW WORDS ABOUT LECTURER

Nataliya Bogushevskaya

• Ukraine, Kyiv

• Software Testing Team Leader

• Nataliya_Bogushevskaya@epam.com

• Experience:

• 7 years in EPAM

• More than 15 years of production projects (Oracle, Sybase, SQL Server)

CONFIDENTIAL 2
AGENDA

1. PIVOT and UNPIVOT


2. Hierarchical queries with CONNECT BY

CONFIDENTIAL 3
PIVOT AND UNPIVOT

CONFIDENTIAL 4
TASK

Let’s assume, that we have to output the amount of employees by mentioned below jobs:
• SA_REP
• SH_CLERK
• ST_CLERK
• SA_MAN
• ST_MAN
in a pivot view:

CONFIDENTIAL 5
DECISIONS
POSSIBLE DECISION

• With CASE (ANSI)


• With DECODE (Oracle)

CONFIDENTIAL 6
USING PIVOT

WITH t AS (SELECT e.department_id, e.job_id


FROM employees e)
SELECT *
FROM t PIVOT (COUNT(*) FOR job_id IN ('SA_REP',
'SH_CLERK',
'ST_CLERK',
'SA_MAN',
'ST_MAN'));

CONFIDENTIAL 7
TASK

Print out the total salary of employees in each department by mentioned below jobs:
• SA_REP
• SH_CLERK
• ST_CLERK
• SA_MAN
• ST_MAN
in a pivot view:

CONFIDENTIAL 8
SEVERAL AGGREGATE FUNCTIONS

Print out the amount of employees and corresponding total salary for jobs 'SA_REP',
'SH_CLERK', 'ST_CLERK‘ for each department.

WITH t AS (SELECT e.department_id, e.job_id,e.salary


FROM employees e)
SELECT *
FROM t PIVOT (COUNT(*) AS qty,
SUM(salary) AS Sal
FOR job_id IN ('SA_REP', 'SH_CLERK', 'ST_CLERK'));

Note. Column names by default are composed as


<value alias>_<aggregate alias>.
So, only one among several aggregates may have no value.

CONFIDENTIAL 9
SETS OF VALUES IN PIVOT

Find out the amount of employee, hired in 2005 on 'ST_MAN‘ position or in 2007 on
'ST_CLERK‘ position. List:
- department_id
- corresponding amounts in separate columns.
WITH t AS (SELECT e.department_id,
e.job_id,
EXTRACT (YEAR FROM e.hire_date) AS hire
FROM employees e)
SELECT *
FROM t PIVOT (COUNT(*)
FOR (job_id, hire) IN (('ST_MAN',2005) AS stm_2005,
('ST_CLERK',2007) AS stc_2007));

CONFIDENTIAL 10
ANY IN PIVOT

List the amount of employees for each job


WITH t AS (SELECT e.department_id, e.job_id, e. employee_id
FROM employees e)
SELECT *
FROM t PIVOT XML (COUNT (employee_id) FOR job_id IN (ANY));

<PivotSet>
<item>
<column name = "JOB_ID">SH_CLERK</column>
<column name = "COUNT(*)">20</column>
</item>
<item>
<column name = "JOB_ID">ST_CLERK</column>
<column name = "COUNT(*)">20</column>
</PivotSet>

CONFIDENTIAL 11
SUBQUERY IN PIVOT

List the amount of employees on the most highly payed job for each department
WITH t AS (SELECT e.department_id, e.job_id, e. employee_id
FROM employees e)
SELECT *
FROM t PIVOT XML (COUNT (employee_id)
FOR job_id IN (SELECT job_id
FROM jobs
WHERE max_salary =
(SELECT MAX(max_salary)FROM jobs)));

<PivotSet>
<item>
<column name = "JOB_ID">AD_PRES</column>
<column name = COUNT(EMPLOYEE_ID)">0</column>
</item>
</PivotSet>

CONFIDENTIAL 12
USEFUL PIVOT FACTS

• Pivot is executed before any joins or where clauses.

• All columns not mentioned in aggregation clause or in for clause are used as GROUP BY
criteria.

CONFIDENTIAL 13
PRACTICE #1

For each department having employees show the number of people working as
'SA_REP','ST_CLERK','IT_PROG' as well as total salary of such people:

CONFIDENTIAL 14
PRACTICE #2

Show the number of hired people for each year and each month. Take into account
current employees only:

CONFIDENTIAL 15
UNPIVOT

• Reverse PIVOT operation. It converts several columns into values of one


column.
• It can’t undo aggregation

Sales value for


some product

CONFIDENTIAL 16
UNPIVOT

SELECT *
FROM unpivot_test UNPIVOT (sales FOR YEAR IN ("2014","2015","2016"));

CONFIDENTIAL 17
UNPIVOT AND NULL VALUES

SELECT *
FROM unpivot_test UNPIVOT (sales FOR YEAR IN ("2014","2015","2016"))
WHERE country_name = 'Belgium'

CONFIDENTIAL 18
UNPIVOT AND NULL VALUES

SELECT *
FROM unpivot_test UNPIVOT INCLUDE NULLS
(sales FOR YEAR IN ("2014","2015","2016"))
WHERE country_name = 'Belgium';

CONFIDENTIAL 19
HIERARCHICAL QUERIES
WITH CONNECT BY
(ORACLE)

CONFIDENTIAL 20
HIERARCHICAL DATA

Hierarchical data is defined as a set of data items that are related to each
other by hierarchical relationships.
Hierarchical relationships exist where one item of data is the parent of another
item.
Examples of the hierarchical data that is commonly stored in databases include
the following:
• an organizational structure
• a file system
• a set of tasks in a project
• a graph of links between Web pages

CONFIDENTIAL 21
HIERARCHICAL DATA

ROOT

CONFIDENTIAL 22
CONNECT BY

Hierarchical query clause

• START WITH specifies the root row(s) of the hierarchy (not mandatory);
• PRIOR operator refers to the parent row;
• CONNECT BY specifies the relationship between parent rows and child rows of the
hierarchy.

CONFIDENTIAL 23
EXAMPLE

List all managers for some employee:

SELECT employee_id, manager_id, first_name, last_name


FROM employees

START WITH employee_id = 108 Starting point

CONNECT BY employee_id = PRIOR manager_id;

CONFIDENTIAL 24
EXAMPLE

List all subordinates for some employee:

SELECT employee_id, manager_id, first_name, last_name


FROM employees

START WITH employee_id = 108 Starting point

CONNECT BY PRIOR employee_id = manager_id;

CONFIDENTIAL 25
PRACTICE

Select all subordinates of Steven King

CONFIDENTIAL 26
EXECUTION

Oracle processes hierarchical queries as follows:


1. joins;
2. start with/connect by;
3. where;
4. group by and having;
5. order by.

CONFIDENTIAL 27
OPERATORS AND PSEUDOCOLUMNS

PRIOR

• PRIOR – retrieves previous filed in SELECT-clause

For each employee get his/her manager name

SELECT employee_id, manager_id, first_name, last_name


, PRIOR first_name AS m_first_name, PRIOR last_name
AS m_last_name
FROM employees
CONNECT BY PRIOR employee_id = manager_id
START WITH manager_id IS NULL;

CONFIDENTIAL 28
OPERATORS AND PSEUDOCOLUMNS

LEVEL

• LEVEL – returns 1 for a root row, 2 for a child of a root, and so on.

For each employee determine her/his level in hierarchy

SELECT employee_id, manager_id, first_name, last_name,LEVEL


FROM employees
CONNECT BY PRIOR employee_id = manager_id
START WITH manager_id IS NULL;

CONFIDENTIAL 29
PRACTICE

Print list of employees in a tree-view

Note. Use LPAD(' ',(LEVEL-1)*3,'-') for the shifting

CONFIDENTIAL 30
PRACTICE

Generate sequential numbers from 1 to 100

CONFIDENTIAL 31
PRACTICE

Generate dates from now (sysdate) till the end of the year.

CONFIDENTIAL 32
PRACTICE

Select all managers of employee with phone_number = '650.505.2876'. Don't


show the actual employee.

CONFIDENTIAL 33
PRACTICE

The table contains the ordered set or numbers, for example (3, 6, 8, 9, 11 , …).
Return three smallest missing numbers (4, 5, 7).

CONFIDENTIAL 34
PRACTICE

Table contains one row and one field. This field stores some arithmetical
expression with numbers, arithmetic signs and parenthesis’s. For example,
2*((5+7)+2*(2+3))*8)+9
Write a query that will return each symbol from the string as a separate row.

CONFIDENTIAL 35
OPERATORS AND PSEUDOCOLUMNS

SYS_CONNECT_BY_PATH(column, delimiter)

• SYS_CONNECT_BY_PATH – returns the path of a column value from root to node;

For each employee of the 4th level list the full path from the root manager

SELECT e.first_name, e.last_name,


sys_connect_by_path(last_name||' '||first_name,'\') AS org
FROM employees e
WHERE LEVEL = 4
CONNECT BY e.manager_id = PRIOR e.employee_id
START WITH e.employee_id = 100;

CONFIDENTIAL 36
OPERATORS AND PSEUDOCOLUMNS

CONNECT_BY_ROOT

• CONNECT_BY_ROOT - references to the hierarchy root


SELECT last_name Employee,
King CONNECT_BY_ROOT last_name head_manager,
PRIOR last_name AS direct_manager,
LEVEL-1 Pathlen,
Kochhar SYS_CONNECT_BY_PATH(last_name, '/') PATH
FROM employees
Higgins WHERE department_id = 110
CONNECT BY PRIOR employee_id = manager_id
ORDER BY Employee,Pathlen
Gietz

CONFIDENTIAL 37
PRACTICE

For each employee of the 4th level list the full path to the root manager

CONFIDENTIAL 38
OPERATORS AND PSEUDOCOLUMNS

CONNECT_BY_ISLEAF

• CONNECT_BY_ISLEAF – returns 1 for nodes having no children (a leaf), 0 for others

Print all employees of the 3rd level who hasn’t subordinates


SELECT last_name AS Employee,
LEVEL, SYS_CONNECT_BY_PATH(last_name, '/') Path
FROM employees
WHERE CONNECT_BY_ISLEAF = 1
AND LEVEL = 3
START WITH employee_id = 100
CONNECT BY PRIOR employee_id = manager_id
ORDER BY manager_id;

CONFIDENTIAL 39
PRACTICE

Find the manager with only one subordinate, who, in turn, has no subordinates

CONFIDENTIAL 40
ORDERING DATA

ORDER SIBLINGS BY – preserves hierarchical ordering

SELECT e.first_name, e.last_name,


sys_connect_by_path(last_name,'\') as org
FROM employees e
CONNECT BY e.manager_id = PRIOR e.employee_id
START WITH e.employee_id = 100
ORDER SIBLINGS BY first_name,last_name;

CONFIDENTIAL 41
PRACTICE

For each employee show his/her salary and summary salary of all his/her
managers. Preserve tree structure in ascending order by salary in output.

CONFIDENTIAL 42
LOOPS

Let’s assume, that some data were modified in the current table:

--set Boss for the root row


UPDATE employees
SET manager_id = 145
WHERE employee_id = 100;

SELECT e.first_name, e.last_name,


sys_connect_by_path(last_name,'\') as org
FROM employees e
CONNECT BY e.manager_id = PRIOR e.employee_id
START WITH e.employee_id = 100
ORDER SIBLINGS BY first_name,last_name;

CONFIDENTIAL 43
LOOPS

NOCYCLE parameter is used to avoid an error and to detect which row is cycling

SELECT e.first_name, e.last_name,


sys_connect_by_path(last_name,'\') as org
FROM employees e
CONNECT BY NOCYCLE e.manager_id = PRIOR e.employee_id
START WITH e.employee_id = 100
ORDER SIBLINGS BY first_name,last_name;

CONFIDENTIAL 44
LOOPS

CONNECT_BY_ISCYCLE - pseudocolumn shows which rows contain the cycle

SELECT e.first_name, e.last_name,


sys_connect_by_path(last_name,'\') as org
FROM employees e
WHERE CONNECT_BY_ISCYCLE = 1
CONNECT BY NOCYCLE e.manager_id = PRIOR e.employee_id
START WITH e.employee_id = 100
ORDER SIBLINGS BY first_name,last_name;

CONFIDENTIAL 45
USEFUL LINKS

Oracle documentation -
https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm

CONFIDENTIAL 46
On-line DB (Oracle)

https://livesql.oracle.com/apex/livesql/file/index.html

CONFIDENTIAL 47
THANK YOU!

CONFIDENTIAL 48

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy