0% found this document useful (0 votes)
25 views29 pages

SQL 1729279618

Uploaded by

swik
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)
25 views29 pages

SQL 1729279618

Uploaded by

swik
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/ 29

SQL Beginner to

Advanced
By Fayaz
SQL is a very simple, yet powerful, database access language. SQL is a non-procedural language; users
describe in SQL what they want done, and the SQL language compiler automatically generates a
procedure to navigate the database and perform the desired task.

Oracle SQL includes many extensions to the ANSI/ISO standard SQL language, and Oracle tools and
applications provide additional commands. The Oracle tools SQL*Plus and Server Manager allow you to
execute any ANSI/ISO standard SQL statement against an Oracle database, as well as additional
commands or functions that are available for those tools.

SQL processing is the parsing, optimization, row source generation, and execution of a SQL statement.
Depending on the statement, the database may omit some of these stages.

There is a parser inside Oracle, which parses the SQL Query for further processing.
The first 3 steps of SQL Query Execution are taken care of by the parser.
Step 1: Syntax check

This checks only for syntax errors. A pure syntax check and nothing else.
Examples:
1. Are the keywords correct? Like, 'select', 'form', 'groupby', 'orderby' are few common spelling
mistakes.
2. Does SQL Query end with a semicolon (;)?
3. Are column names in the 'Select' Clause are separated by commas (,)?
4. Does 'Select' clause include only the colmuns which are present in the 'Group by' clause?
5. Does 'Group by' clause appear after 'Where clause'?
6. Is 'Order by' clause the last clause in the query? etc. etc....

In each of these cases, if the answer is 'No', oracles throws an error stating the same.

Step 2: Sematic check


Once the query passes the Syntax check, next step is Semantic check.
Here, the references of all objects present in the query are checked along with user privileges. The check
happens against metadata maintained in the Oracle.
Examples:
1. Is table name valid or such a table exists?
2. Are columns names correct?
3. Does user have select/update/delete/insert/create privilege? etc. etc. etc.

So during Syntax check, it doesn't check for the validity of table names, column names, privileges etc.

Let's say, I am running this... "select * from epm;"

This passes Syntax check, though I am writing a wrong table name. Instead of "emp", I have written
"epm". But, this query is fine syntax-wise and hence passes the Syntax check. But it fails in the next step
of Semantic check where the object names are verified.

But we will not be able to notice whether a query failed at Syntax check or at Semantic check when we
run a query from SQL*Plus or any other GUI. Because, everything is handled in one go from user point of
view and the errors are sent if the Query fails at any step. Otherwise, we get the final output.

Step 3: Shared pool check


Basically, once the query passed both Syntax check and Semantic check, it goes for third check called
'Shared pool check'.
Just to put it briefly, 'Shared pool' is a memory segment present inside every Oracle instance, which
retains the recently executed SQL and PLSQL code inside its 'Library Cache' based on LRU algorithm.

So, if parser finds that the query is present inside 'Library Cache' or 'Shared pool', then it is called 'Soft
Parse'. It goes to step 5, executes the query and sends the output to whoever requested it.

As simple as that. But, if parser finds that such a query is not present inside 'Shared pool' or 'Library
Cache', then it is called 'Hard Parse'. So, Oracle must carry out step 4 first to prepare the query and then
go to step 5 finally to execute the query and then send the output to the requestor.
So, the first three steps are always carried out for every SQL Query and they are less expensive.

Step 4:
The step 4 is very expensive or costly. Meaning, it consumes lot of resources to complete this, like CPU,
I/O reads, physical reads, extra algorithms to generate multiple queries and select the best one etc.

Hence, 'Hard Parse' degrades performance. We should keep this in mind always before writing any
query. To put it simply for now, avoid hard coding and use bind variables to take the advantage of 'Soft
Parse'.

Step 4 happens only in case of 'Hard parse', which is decided in step 3 as we discussed above.

We can split this into two sub-steps.


a. Optimization: The Optimizer generates multiple plans using various combinations of joins
(Nested loop/Sort Merge/Hash), access paths (full table scan/index range scan/index skip scan
etc) and join orders.
Finally selects the best plan based on cost. The lower the cost, the better the performance.

b. Row source generation: The row source generator is software that receives the optimal execution
plan from the optimizer and produces an iterative execution plan that is usable by the rest of the
database.

The row source generator produces a row source tree, which is a collection of row sources. The row
source tree shows the following information:

• An ordering of the tables referenced by the statement

• An access method for each table mentioned in the statement

• A join method for tables affected by join operations in the statement

• Data operations such as filter, sort, or aggregation

The execution plan for this statement is the output of the row source generator.

SELECT e.last_name, j.job_title, d.department_name


FROM hr.employees e, hr.departments d, hr.jobs j
WHERE e.department_id = d.department_id
AND e.job_id = j.job_id
AND e.last_name LIKE 'A%';
Execution Plan
----------------------------------------------------------
Plan hash value: 975837011
--------------------------------------------------------------------------------
| Id| Operation | Name |Rows|Bytes|Cost(%CPU)|Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 189 | 7(15)| 00:00:01 |
|*1 | HASH JOIN | | 3 | 189 | 7(15)| 00:00:01 |
|*2 | HASH JOIN | | 3 | 141 | 5(20)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 3 | 60 | 2 (0)| 00:00:01 |
|*4 | INDEX RANGE SCAN | EMP_NAME_IX | 3 | | 1 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | JOBS | 19 | 513 | 2 (0)| 00:00:01 |
| 6 | TABLE ACCESS FULL | DEPARTMENTS | 27 | 432 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
2 - access("E"."JOB_ID"="J"."JOB_ID")
4 - access("E"."LAST_NAME" LIKE 'A%')
filter("E"."LAST_NAME" LIKE 'A%')

None of this happens in case of 'Soft Parse' and hence improves performance.

Step 5: Query Execution

Step 5 is again common for each query irrespective of whether it is 'Soft Parse' or 'Hard Parse'.
During execution, the SQL engine executes each row source in the tree produced by the row source
generator. This step is the only mandatory step in DML processing.

SQL sublanguage commands:


SQL Commands are mainly categorized into five categories

DQL (Data Query Language): SELECT, FROM, WHERE and ORDER BY.
DML (Data Manipulation Language): INSERT, DELETE and UPDATE
TCL (Transaction Control Language): BEGIN TRANSACTION, SAVEPOINT, COMMIT and ROLLBACK
DDL (Data Definition Language): CREATE, ALTER, TRUNCATE and DROP
DCL (Data Control Language): GRANT and REVOKE
Oracle data types
NUMBER – store numeric values that can be negative or positive

CREATE TABLE number_demo (


number_value NUMERIC(6, 2)
);

FLOAT – The Oracle FLOAT data type is the subtype of the NUMBER data type. Its main purpose is to
facilitate compatibility with ANSI SQL FLOAT data types.

CREATE TABLE float_demo (


f1 FLOAT(1)
);

CHAR – to store fixed-length character strings.


VARCHAR2 – To store variable-length character strings, you use the Oracle VARCHAR2 data type.
A VARCHAR2 column can store a value that ranges from 1 to 4000 bytes. It means that for a single-byte
character set, you can store up to 4000 characters in a VARCHAR2 column.
Since Oracle Database 12c, you can specify the maximum size of 32767 for the VARCHAR2 data type.
Oracle uses the MAX_STRING_SIZE parameter for controlling the maximum size.
CREATE TABLE employee(
first_name VARCHAR2( 20 ) NOT NULL
);

In addition, if you store 10 characters in a VARCHAR2(20) column, Oracle uses only 10 bytes for storage,
not 20 bytes. Therefore, using VARCHAR2 data type helps you save spaces used by the table.

DATE – to store Dates.

CREATE TABLE my_events (


event_id NUMBER GENERATED BY DEFAULT AS IDENTITY,
event_name VARCHAR2 ( 255 ) NOT NULL,
location VARCHAR2 ( 255 ) NOT NULL,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
PRIMARY KEY ( event_id )
);
The standard date format for input and output is DD-MON-YY e.g., 01-JAN-17

TIMESTAMP – The TIMESTAMP data type allows you to store date and time data including year, month,
day, hour, minute, and second.

CREATE TABLE logs (


log_id NUMBER GENERATED BY DEFAULT AS IDENTITY,
message VARCHAR(2) NOT NULL,
logged_at TIMESTAMP (2) NOT NULL,
PRIMARY KEY (log_id)
);

Delete Vs Truncate:
When you want to delete all data from a table, you use the DELETE statement without the
WHERE clause as follows:
DELETE FROM table_name;

For a table with a small number of rows, the DELETE statement does a good job. However, when you
have a table with a large number of rows, using the DELETE statement to remove all data is not efficient.
Oracle introduced the TRUNCATE TABLE statement that allows you to delete all rows from a big table.

--below query creates the table


CREATE TABLE ot.persons(
person_id NUMBER GENERATED BY DEFAULT AS IDENTITY,
first_name VARCHAR2(50) NOT NULL,
last_name VARCHAR2(50) NOT NULL,
PRIMARY KEY(person_id)
);
--below query adds a new column to the table ‘members’
ALTER TABLE members ADD birth_date DATE NOT NULL;

--to drop columns


ALTER TABLE suppliers
DROP ( email, phone );

--increase column width


ALTER TABLE accounts
MODIFY phone VARCHAR2( 15 );

To delete rows
DELETE FROM table_name;

--to delete all the rows


TRUNCATE TABLE customers;

--rename table
RENAME table_name TO new_name;

Oracle Constrains:

An Oracle NOT NULL constraint specifies that a column cannot contain NULL values.

Oracle unique constraint:


A unique constraint is an integrity constraint that ensures the data stored in a column, or a group of
columns, is unique among the rows in a table.

CREATE TABLE clients (


client_id NUMBER GENERATED BY DEFAULT AS IDENTITY,
first_name VARCHAR2(50) NOT NULL,
last_name VARCHAR2(50) NOT NULL,
company_name VARCHAR2(255) NOT NULL,
email VARCHAR2(255) NOT NULL UNIQUE,
phone VARCHAR(25)
);

PRIMARY KEY:
A primary key is a column of a combination of columns in a table that uniquely identifies a row in the
table.
The following are rules that make a column a primary key:
• A primary key column cannot contain a NULL value or an empty string.
• A primary key value must be unique within the entire table.
• A primary key value should not be changed over time.
CREATE TABLE purchase_order_items (
po_nr NUMBER NOT NULL,
item_nr NUMBER NOT NULL,
product_id NUMBER NOT NULL,
quantity NUMBER NOT NULL,
purchase_unit NUMBER NOT NULL,
buy_price NUMBER (9,2) NOT NULL,
delivery_date DATE,
PRIMARY KEY (po_nr, item_nr)
);

CREATE TABLE vendors (


vendor_id NUMBER,
vendor_name VARCHAR2(255) NOT NULL,
address VARCHAR2(255) NOT NULL
);

ALTER TABLE vendors


ADD CONSTRAINT pk_vendors PRIMARY KEY (vendor_id);

Oracle foreign key constraint


A foreign key is all about the relationship.

The group_id in the suppliers table is used for establishing the relationship between rows in
the suppliers and supplier_groups tables.
Before inserting a row into the suppliers table, you have to look up an existing group_id in
the supplier_groups table and use this value for insertion.

CREATE TABLE supplier_groups(


group_id NUMBER GENERATED BY DEFAULT AS IDENTITY,
group_name VARCHAR2(255) NOT NULL,
PRIMARY KEY (group_id)
);

CREATE TABLE suppliers (


supplier_id NUMBER GENERATED BY DEFAULT AS IDENTITY,
supplier_name VARCHAR2(255) NOT NULL,
group_id NUMBER NOT NULL,
PRIMARY KEY(supplier_id)
);

Oracle Check constraint


An Oracle check constraint allows you to enforce domain integrity by limiting the values accepted by
one or more columns
CREATE TABLE parts (
part_id NUMBER GENERATED BY DEFAULT AS IDENTITY,
part_name VARCHAR2(255) NOT NULL,
buy_price NUMBER(9,2) CHECK(buy_price > 0),
PRIMARY KEY(part_id)
);

DATE Queries:
select trunc((to_date('2021-05-02', 'YYYY-MM-DD')-to_date('2020-01-02','YYYY-MM-DD')))
from dual;--days
select trunc((to_date('2021-05-02', 'YYYY-MM-DD')-to_date('2020-01-02','YYYY-MM-
DD'))/365) from dual; --years
select months_between(to_date('2021-05-02', 'YYYY-MM-DD'),to_date('2020-01-02','YYYY-MM-
DD')) from dual;--months
SELECT ADD_MONTHS(SYSDATE, -1) AS PREV_MONTH, SYSDATE AS CURRENT_DATE,
ADD_MONTHS(SYSDATE, 1) as NEXT_MONTH from dual;
SELECT SYSDATE AS CURRENT_DATE_TIME, EXTRACT(Year FROM SYSDATE),EXTRACT(day FROM
SYSDATE),EXTRACT(Month FROM SYSDATE) AS ONLY_CURRENT_YEAR FROM Dual;
SELECT SYSDATE AS CURRENT_DATE, LAST_DAY(SYSDATE) AS LAST_DAY_OF_MONTH,
LAST_DAY(SYSDATE)+1 AS FIRST_DAY_OF_NEXT_MONTH
FROM Dual;

SELECT TO_CHAR(DATE '2035-09-26', 'Day, DD Month YYYY') FROM DUAL;-- Wednesday, 26


September 2035
select TO_CHAR(e.emp_status_date, 'Day, DD Month YYYY') from employee e;

select to_number(to_char(e.hiredate,'YYYY')) as Year,to_number(to_char(e.hiredate,'MM'))


as month,count(1) as NO_OF_EMPS_JOINED from
emp e group by
to_number(to_char(e.hiredate,'YYYY')),to_number(to_char(e.hiredate,'MM'))

REGEX
select regexp_replace('fayaz&&&*%&*%$' , '\&|\*|\;|\:|\#|\$|\-|\,|\^|\~|\`|\%|\_','') from dual;

select * from employee where REGEXP_LIKE(ssn,


'"111111111|000000000|222222222|333333333|444444444"')

DECODE:
SELECT DECODE ('F', 'F', 'FEMALE',
'M', 'MALE'
) as Gender FROM dual;
COALESCE: returns first not null value in the list.
The COALESCE() function uses short-circuit evaluation. It means that the function stops evaluating the
remaining expressions once it finds the first one evaluates to a non-null value.

SELECT COALESCE(NULL,'A','B') result FROM dual;

CASE Expression:
The CASE expression goes through conditions and returns a value when the first condition is met (like an
if-then-else statement). So, once a condition is true, it will stop reading and return the result. If no
conditions are true, it returns the value in the ELSE clause.

SELECT OrderID, Quantity,


CASE
WHEN Quantity > 30 THEN 'The quantity is greater than 30'
WHEN Quantity = 30 THEN 'The quantity is 30'
ELSE 'The quantity is under 30'
END AS QuantityText
FROM OrderDetails;

Oracle COALESCE() and CASE expression


You can use the COALESCE() function instead of the longer CASE expression when it comes to test for
null in multiple expressions. The COALESCE() function is more concise than a CASE expression that
involves null evaluations.
COALESCE(e1, e2)

CASE
WHEN e1 IS NOT NULL THEN
e1
ELSE
e2
END

NVL() function:
SELECT nvl(sal,0)as salary from emp;
SELECT
NVL(1,1/0)
FROM
dual;

Oracle COALESCE() vs. NVL()


The COALESCE() function is a part of SQL ANSI-92 standard while NVL() function is Oracle specific.
the COALESCE() function only evaluates the first expression to determine the result while the NVL()
function evaluates both expressions.
Global Temporary Tables (GTTs) are the Oracle tables, having data type as private; such that data
inserted by a session can be accessed by that session only.

Global Temporary Table has two options:


1. ON COMMIT DELETE ROWS
Clause make sure data deleted at the end of the transaction or the end of the session level.

2. ON COMMIT PRESERVE ROWS


Clause make sure data remain persistent at the end of the transaction. Only be removed at the end of
the session or manually delete command.

CREATE GLOBAL TEMPORARY TABLE temp_customers (


id NUMBER(10),
cust_name VARCHAR2(100)
) ON COMMIT DELETE ROWS;

GROUP BY:
The GROUP BY clause is a SQL command that is used to group rows that have the same values.
select d.did,sum(e.SAL) AS names from emp e, dept d where e.did=d.did group by d.did

Although the below queries generate the same output, the logic is totally different. The WHERE clause is
executed before GROUP BY, so essentially it scans entire dataset for the given condition.
However, HAVING is executed after GROUP BY, so it scans comparatively small number of records as
rows are already grouped together. So HAVING is a time-saver.

-- WHERE clause
SELECT Product_Category,
Sales_Manager,
Shipping_Cost
FROM Dummy_Sales_Data_v1
WHERE Shipping_Cost >= 34
GROUP BY Product_Category,
Sales_Manager,Shipping_Cost

-- HAVING clause
SELECT Product_Category,
Sales_Manager,
Shipping_Cost
FROM Dummy_Sales_Data_v1
GROUP BY Product_Category,
Sales_Manager,
Shipping_Cost
HAVING Shipping_Cost >= 34

LISTAGG
select d.did,LISTAGG (e.ename, ',' ON OVERFLOW TRUNCATE)
WITHIN GROUP (ORDER BY d.did) AS names from emp e, dept d where e.did=d.did group by
d.did

select d.did,LISTAGG (e.ename, ',' ON OVERFLOW TRUNCATE)


WITHIN GROUP (ORDER BY e.ename desc) AS names from emp e, dept d where e.did=d.did group
by d.did

ON OVERFLOW ERROR If you specify this clause, then the function returns an ORA-01489 error. This is
the default.
ON OVERFLOW TRUNCATE If you specify this clause, then the function returns a truncated list of
measure values.

Group BY Rollup expression:


the ROLLUP operator is used to calculate sub-totals and grand totals for a set of columns passed to the
“GROUP BY ROLLUP” clause.
https://www.sqlservercentral.com/articles/the-difference-between-rollup-and-cube

Let’s see how the ROLLUP clause helps us calculate the total salaries of the employees grouped by their
departments and the grand total of the salaries of all the employees in the company.

SELECT did ,sum(sal) from emp


GROUP BY rollup(did);

-- Finding Subtotals Using ROLLUP Operator


SELECT
coalesce (dname, 'All Departments') AS Department,
coalesce (gender,'All Genders') AS Gender,
sum(sal) as Salary_Sum
FROM emp e, dept d where e.did=d.did
GROUP BY ROLLUP (dname, gender);

GROUP BY CUBE expression:


The CUBE is an extension of the GROUP BY clause that allows you to generate grouping sets for all possible
combinations of dimensions.

The CUBE operator is also used in combination with the GROUP BY clause, however the CUBE operator produces
results by generating all combinations of columns specified in the GROUP BY CUBE clause.

SELECT
coalesce (dname, 'All Departments') AS Department,
coalesce (gender,'All Genders') AS Gender,
sum(sal) as Salary_Sum
FROM emp e, dept d where e.did=d.did
GROUP BY CUBE (dname, gender)

we can see the grand total which is total of salaries of employees of all genders and all departments.

DEPT GENDER SUM


All Departments All Genders 39175
All Departments F 5700
All Departments M 33475
QA All Genders 6000
QA M 6000
DBA All Genders 3550
DBA F 1100
DBA M 2450
DEV All Genders 22175
DEV F 4600
DEV M 17575
MANAGEMENT All Genders 7450
MANAGEMENT M 7450

There is only one major difference between the functionality of the ROLLUP operator and the CUBE
operator. ROLLUP operator generates aggregated results for the selected columns in a hierarchical way.
On the other hand, CUBE generates a aggregated result that contains all the possible combinations for
the selected columns.

SQL Joins:
1.CROSS JOIN: Returns rows which combine each row from the first table with each row from the
second table

2.INNER JOIN: Inner join can have equality (=) and other operators (like <,>,<>) in the join condition.
SELECT * FROM test1,test2 WHERE test1.SNo > test2.SNo;

3.EQUI JOIN: Equi join only have an equality (=) operator in the join condition. Equi join can be an Inner
join, Left Outer join, Right Outer join

SELECT * FROM tblEmp JOIN tblDept ON tblEmp.DeptID = tblDept.DeptID;


SELECT * FROM tblEmp INNER JOIN tblDept USING(DeptID)

3.NATUAL JOIN: A natural join is a type of equi join which occurs implicitly by comparing all the same
names columns in both tables. The join result has only one column for each pair of equally named
columns.

4.LEFT OUTER/LEFT JOIN: Also returns the rows from Left table which didn’t matched join condition
5.RIGHT OUTER/RIGHT JOIN: Also returns the rows from Right table which didn’t matched join condition

6.FULL OUTER JOIN: Also returns the rows from Left and Right table which didn’t matched join
condition

7.SELF JOIN: joining a table itself.

https://www.dotnettricks.com/learn/sqlserver/difference-between-inner-join-and-equi-join-and-natural-
join#:~:text=A%20natural%20join%20is%20a,attribute%20name%20and%20the%20datatypes.
https://database.guide/sql-inner-join/

Sub Queries:
a subquery in the WHERE clause acts as a filter, and a subquery in the FROM clause acts as a view, then
a subquery in the SELECT clause acts like a column that is to be shown in your output.

Subqueries in a WHERE Clause


Single Row Sub Query:
SELECT * FROM emp
WHERE sal > (
SELECT AVG(sal)
FROM emp
);

SELECT first_name, salary, department_id


FROM employee
WHERE salary = (SELECT MIN (salary)
FROM employees);
Multiple Row Sub queries:
SELECT first_name, department_id
FROM employees
WHERE department_id IN (SELECT department_id
FROM departments
WHERE LOCATION_ID = 100)

Multiple Column Sub Query


A multiple-column subquery returns more than one column to the outer query and can be listed in the outer
query's FROM, WHERE, or HAVING clause.
SELECT * FROM emp
WHERE (sal, did) in (SELECT sal, did
FROM emp WHERE sal BETWEEN 1000 and 2000 AND did BETWEEN 10 and 20)
Inline Views: Subqueries in a FROM Clause
SELECT
sub.dept_id,
d.dept_name,
sub.avg_salary
FROM
(
SELECT dept_id, ROUND(AVG(salary), 2) AS avg_salary
FROM employee
GROUP BY dept_id
) sub
INNER JOIN department d ON sub.dept_id = d.id;

Subqueries in a SELECT Clause


SELECT id, last_name, salary, (
SELECT AVG(salary)
FROM employee
) AS avg_salary
FROM employee;

4. Multiple Subqueries (Nested Subqueries)


SELECT job_id,AVG(salary)
FROM employees
GROUP BY job_id
HAVING AVG(salary)<
(SELECT MAX(AVG(min_salary))
FROM jobs
WHERE job_id IN
(SELECT job_id FROM job_history
WHERE department_id
BETWEEN 50 AND 100)
GROUP BY job_id);
Correlated Subqueries: Correlated subqueries are used for row-by-row processing. Each subquery is executed
once for every row of the outer query.

Now, to find the employees with a salary greater than the average salary in their department
SELECT e.id, e.last_name, e.salary, e.dept_id
FROM employee e
WHERE e.salary > (
SELECT AVG(s.salary)
FROM employee s
WHERE s.dept_id = e.dept_id
GROUP BY s.dept_id
);
Find employees who have at least one person reporting to them.
SELECT * FROM emp e1 WHERE EXISTS ( SELECT 1 FROM emp e2 WHERE e2.mgr =e1.empno);
Find all departments that do not have any employees.
SELECT department_id, department_name
FROM departments d
WHERE NOT EXISTS (SELECT ’X’
FROM employees
WHERE department_id
= d.department_id);

Oracle correlated subquery in the SELECT clause example


SELECT
product_id,
product_name,
standard_cost,
ROUND(
(
SELECT
AVG( standard_cost )
FROM
products
WHERE
category_id = p.category_id
),
2
) avg_standard_cost
FROM
products p
ORDER BY
product_name;

Inline Views:
An inline view is not a real view but a subquery in the FROM clause of a SELECT statement. Consider
the following SELECT statement:

SELECT
*
FROM
(
SELECT
product_id,
product_name,
list_price
FROM
products
ORDER BY
list_price DESC
)
WHERE
ROWNUM <= 10;

Pivot:
For transposing rows and columns, or transposing columns and rows. It can be done in a couple of ways
in SQL, and the easiest is to use the Oracle PIVOT keyword.

STEPS in the PIVOT:


1.The first step is separate all rows.
2. We need to aggregate the required data using the aggregate functions like Sum,Avg,Min,Max,Count
function.
3. Convert(transpose) aggregated data into columns:

PIVOT syntax:
SELECT
select_list
FROM
table_name
PIVOT [XML] (
pivot_clause
pivot_for_clause
pivot_in_clause
);

pivot_clause specifies the column(s) that you want to aggregate. The pivot_clause performs an implicitly
GROUP BY based on all columns which are not specified in the clause, along with values provided by the
pivot_in_clause.
pivot_for_clause specifies the column that you want to group or pivot.
pivot_in_clause defines a filter for column(s) in the pivot_for_clause. The aggregation for each value in
the pivot_in_clause will be rotated into a separate column.

Select * from
(Select did from emp e)
PIVOT (
count(1) FOR did IN (10,20,30,40)
);
PIVOT with XML and ANY: It creates the output in XML.
You cannot use a subquery in the pivot_in_clause. This restriction is relaxed with the XML option:
Select * from
(Select did,sal from emp e)
PIVOT xml(
count(1),
sum(sal) FOR did IN (select distinct did from dept)
););
Pivoting multiple columns and aliasing
Select * from
(Select did,sal from emp e)
PIVOT (
count(1) dept_cnt,
sum(sal) dept_total_salary FOR did IN (10 ,20,30,40)
);

Limit the Number of Rows:


For fetching first 2 rows
SELECT * FROM (
SELECT *
FROM emp
ORDER BY first_name
)
WHERE ROWNUM <= 2;
Pagination:
1.ASK TOM:
SELECT * FROM (
SELECT /*+ FIRST_ROWS(n) */
t.*, ROWNUM rnum FROM (
SELECT *
FROM yourtable
ORDER BY name
) t
WHERE ROWNUM <= :MAX_ROW_TO_FETCH)
WHERE rnum >= :MIN_ROW_TO_FETCH;
2.Analytical function:
SELECT * FROM (
SELECT t.*, ROW_NUMBER() OVER (ORDER BY name) rnum
FROM yourtable t
) WHERE rnum BETWEEN 51 AND 60;

3. This query will get you the first 10 rows, starting from row 51, as an “offset” has been applied on the first 50
rows.
SELECT *
FROM yourtable
ORDER BY name
OFFSET 50 ROWS FETCH NEXT 10 ROWS ONLY;

Delete duplicate rows from a table:


DELETE FROM table a
WHERE a.ROWID IN
(SELECT ROWID FROM
(SELECT
ROWID,
ROW_NUMBER() OVER
(PARTITION BY unique_columns ORDER BY ROWID) dup
FROM table)
WHERE dup > 1);

DELETE FROM your_table


WHERE rowid not in (
SELECT MIN(rowid)
FROM your_table
GROUP BY column1, column2, column3
);

ROW_NUMBER() is an analytic function that assigns a sequential unique integer to each row to which it
is applied, either each row in the partition or each row in the result set.

--For finding highest sal dept wise


select empno,ename,sal,did from (
select empno,ename,sal,did,row_number() over (partition by did order by sal desc) as r
from emp ) where r=1;

RANK(): function is an analytic function that calculates the rank of a value in a set of values.
select empno,ename,sal,did,r from (
select empno,ename,sal,did,rank() over (partition by did order by sal desc) as r from emp
where did=20) where r=1

DENSE_RANK() is an analytic function that calculates the rank of a row in an ordered set of rows.
Unlike the RANK() function, the DENSE_RANK() function returns rank values as consecutive integers. It
does not skip rank in case of ties. Rows with the same values for the rank criteria will receive the same
rank values.
SELECT EMP_ID, DEPT_ID,EXPERTISE,SALARY,
SUM(SALARY) OVER (PARTITION BY DEPT_ID) AS DEPT_SALARY,
SUM(SALARY) OVER (PARTITION BY EXPERTISE) AS EXPERTISE_SALARY,
ROW_NUMBER() OVER (PARTITION BY DEPT_ID ORDER BY SALARY DESC ) AS ROW_NUM ,
RANK() OVER (PARTITION BY DEPT_ID ORDER BY SALARY DESC ) AS RANK_NUM,
DENSE_RANK() OVER (PARTITION BY DEPT_ID ORDER BY SALARY DESC ) AS D_RANK_NUM
FROM EMPLOYEE ORDER BY DEPT_ID,SALARY DESC

Diff between Row Number Vs Rank Vs Dense Rank


Hierarchical Queries:
If a table contains hierarchical data, then you can select rows in a hierarchical order using the
hierarchical query clause.
condition can be any condition as described in Conditions.
START WITH specifies the root row(s) of the hierarchy.
CONNECT BY specifies the relationship between parent rows and child rows of the hierarchy.
LEVEL is a pseudocolumn to show parent and child rows:

SELECT ename, empno, mgr, LEVEL


FROM emp
START WITH empno = 7839
CONNECT BY PRIOR empno = mgr
--ORDER SIBLINGS BY ename;

In a hierarchical query, do not specify either ORDER BY or GROUP BY, as they will override the
hierarchical order of the CONNECT BY results. If you want to order rows of siblings of the same parent,
then use the ORDER SIBLINGS BY clause

https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/Hierarchical-
Queries.html#GUID-E3D35EF7-33C3-4D88-81B3-00030C47AE56

Hints:
Hints enable you to make decisions normally made by the optimizer.
You can use optimizer hints with SQL statements to alter execution plans

Single Table and Multi Table Hints:

SELECT /*+ INDEX (employees emp_department_ix)*/ employee_id, department_id


FROM employees
WHERE department_id > 50;

The parallel hint will open multiple parallel processes to execute the query.

SELECT /*+ PARALLEL(emp, 5) */ last_name FROM employees emp;


The number of parallel processes that can be used is twice the value in the PARALLEL hint

The below tells the optimizer to use the default degree of parallelism determined by the initialization
parameters.

SELECT /*+ FULL(hr_emp) PARALLEL(hr_emp, DEFAULT) */ last_name


FROM employees hr_emp;

SELECT /*+ parallel(l,8) */ last_name FROM employees hr_emp where CREATED_ON > sysdate-1000;

If you want to know which Hint was picked by Query Optimizer execute below Statements.
1.explain plan for
SELECT /*+ parallel(l,8) */ last_name FROM employees hr_emp where CREATED_ON > sysdate-1000;
2.select * from table(dbms_xplan.display);

Views:
a view is a “virtual” table whose data is the result of a stored query, which is derived each time when
you query against the view.
A view is a virtual table because you can use it like a table in your SQL queries.

Unlike a table, a view does not store any data. To be precise, a view only behaves like a table. And it is
just a named query stored in the database. When you query data from a view, Oracle uses this stored
query to retrieve the data from the underlying tables.

CREATE VIEW:
CREATE VIEW Failing_Students AS
SELECT S_NAME, Student_ID
FROM STUDENT
WHERE GPA > 40;
DROP VIEW
Updatable Views:
Inline Views:
An inline view is not a real view but a subquery in the FROM clause of a SELECT statement. Consider the
following SELECT statement:
SELECT
*
FROM
(
SELECT
product_id,
product_name,
list_price
FROM
products
ORDER BY
list_price DESC
)
WHERE
ROWNUM <= 10;
WITH CHECK OPTION

For Listing all tables:

If the user is SYSTEM or has access to dba_tables data dictionary view, then use the given below query:
SELECT owner, table_name FROM dba_tables;

If the user does not have access or privilege to view the dba_tables it can still get a list of all the tables
that it has access to using the following SQL query. This SQL query gives the list of tables that can be
accessed by the user along with its owner.
SELECT owner, table_name FROM all_tables;

This query returns the following list of tables that contain all the tables owned by the user in the entire
database.
SELECT table_name FROM user_tables;

Common Table Expression (CTE):


A common table expression (CTE) is a relatively new SQL feature. It was introduced in SQL:1999, the
fourth SQL revision.

A Common Table Expression (CTE) in SQL is a temporary result set that you can reference within
a SELECT, INSERT, UPDATE, or DELETE statement. It helps to simplify complex queries by breaking them
into more manageable parts.

CTEs allow you to perform multi-level aggregations.


CTEs are also very helpful when you need to organize long and complex queries. Using CTEs will improve
the readability of your code, since it breaks down the code nicely into separate steps. It becomes easier
to change the code or correct errors
WITH grade_average AS (
SELECT s.id,
s.first_name,
s.last_name,
AVG (e.grade) AS average_grade
FROM students s JOIN exams e ON s.id = e.student_id
GROUP BY s.id, s.first_name, s.last_name
)

SELECT first_name,
last_name,
average_grade,
'exceptional' AS tag
FROM grade_average
WHERE average_grade>8.5;

There are two types of CTEs:


• non-recursive
• recursive

Subquery vs CTE: What’s the Difference?


1.CTEs can be recursive
WITH RECURSIVE employee_chain AS (
SELECT
id,
first_name,
last_name,
first_name || ' ' || last_name AS chain
FROM employee
WHERE manager_id IS NULL
UNION ALL
SELECT
employee.id,
employee.first_name,
employee.last_name,
chain || '->' || employee.first_name || ' ' || employee.last_name
FROM employee_chain
JOIN employee
ON employee.manager_id = employee_chain.id
)

SELECT
first_name,
last_name,
chain
FROM employee_chain;

The result will look like this:

first_name last_name chain

Maisy Bloom Maisy Bloom

Caine Farrow Maisy Bloom->Caine Farrow


first_name last_name chain

Waqar Jarvis Maisy Bloom->Caine Farrow->Waqar Jarvis

Lacey-Mai Rahman Maisy Bloom->Caine Farrow->Lacey-Mai Rahman

2. CTEs are reusable

WITH not_null_manager AS (
SELECT
*
FROM employee
WHERE manager_id IS NOT NULL
)

SELECT
nnm1.first_name,
nnm1.last_name,
nnm2.first_name,
nnm2.last_name
FROM not_null_manager AS nnm1
JOIN not_null_manager AS nnm2
ON nnm1.manager_id = nnm2.id;

What is the difference between a btree and a bitmap index:


Internally, a bitmap and a btree indexes are very different, but functionally they are identical in that
they serve to assist Oracle in retrieving rows faster than a full-table scan. The basic differences between
b-tree and bitmap indexes include:

1: Syntax differences: The bitmap index includes the "bitmap" keyword. The btree index does not say
"bitmap".

2: Cardinality differences: The bitmap index is generally for columns with lots of duplicate values (low
cardinality), while b-tree indexes are best for high cardinality columns.

3: Internal structure differences: The internal structures are quite different. A b-tree index has index
nodes (based on data block size), it a tree form:

DB cluster consist of 4 nodes.


From Scan url the request goes to a corresponding node.
Parallel Execution in SQL and PL/SQL:
DBMS_PARALLEL_EXECUTE is an Oracle Supplied package which was introduced with Oracle Database
11g Release 2. It allows you to execute a SQL or PLSQL statement in parallel.

Step 1 Create a task


Step 2 Dividing the table up (chunk)
Step 3 Run Task

DECLARE
v_sql VARCHAR2(32767);
v_status NUMBER;
v_task VARCHAR2(50) := 'fayaz_task';
BEGIN
v_sql := 'update employee s set s.salary = s.salary * 0.10 where rowid BETWEEN
:start_id AND :end_id';

DBMS_PARALLEL_EXECUTE.CREATE_TASK(task_name => v_task);


--dbms_parallel_execute.create_chunks_by_SQL(v_task, 100, FALSE);
dbms_parallel_execute.create_chunks_by_rowid(task_name => v_task,
table_owner => 'TEST',
table_name => 'employee',
by_row => TRUE,
chunk_size => 10000);
DBMS_PARALLEL_EXECUTE.run_task(task_name => v_task,
sql_stmt => v_sql,
language_flag => DBMS_SQL.NATIVE,
parallel_level => 20);
v_status := dbms_parallel_execute.task_status(v_task);
dbms_output.put_line('v_status = ' || v_status);
dbms_parallel_execute.drop_task(v_task);
END;
/

Oracle Virtual Column:


A virtual column is a table column whose values are calculated automatically using other column values,
or another deterministic expression.

In this parts table, the gross_margin column is the virtual column whose values are derived from the list
price and cost columns.

CREATE TABLE parts(


part_id INT GENERATED ALWAYS AS IDENTITY,
part_name VARCHAR2(50) NOT NULL,
capacity INT NOT NULL,
cost DEC(15,2) NOT NULL,
list_price DEC(15,2) NOT NULL,
gross_margin AS ((list_price - cost) / cost),
PRIMARY KEY(part_id)
);

Advantages and disadvantages of virtual columns


Virtual columns consume minimal space. Oracle only stores the metadata, not the data of the virtual
columns.
Virtual columns ensure the values are always in sync with the source columns. For example, if you have
a date column as the normal column and have the month, quarter, and year columns as the virtual
columns. The values in the month, quarter, and year are always in sync with the date column.
Virtual columns help avoid using views to display derived values from other columns.

Virtual columns may reduce query performance because their values are calculated at run-time.

Sharding:
1.Scale up of hardware: We have a limit to increase CPU and RAM
2.Add replicas: IN this Master, child architecture writes goes to one Master node and reads goes to
other nodes. we will be having
Eventual consistency problems.

The solution two above problems is Sharding:

Partition: Table data partitioned based on Partition key on a single DB instance


Sharding: Table Schema replicated in multiple nodes. But Table data distributed across multiple nodes
based on Shard Key.
References:
https://www.databasestar.com/oracle-database/
https://www.oracletutorial.com/oracle-view/inline-view-in-oracle/
https://livesql.oracle.com/apex/livesql/file/content_FHXEW8QV9BNS5LUN2GTMYWWFL.html
https://docs.oracle.com/cd/A57673_01/DOC/server/doc/SCN73/ch11.htm
https://www.databasestar.com/oracle-sql-pivot/
https://www.complexsql.com/pivot-in-sql/
https://learnsql.com/blog/sql-subquery-cte-difference/
https://www.oracletutorial.com/oracle-view/inline-view-in-oracle/
ALL, ANY, EXISTS, NOT EXISTS:
https://www.oracletutorial.com/oracle-basics/oracle-all/
https://www.oracletutorial.com/oracle-basics/oracle-exists/

You might also like