SQL 1729279618
SQL 1729279618
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.
So during Syntax check, it doesn't check for the validity of table names, column names, privileges etc.
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.
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.
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:
The execution plan for this statement is the output of the row source generator.
None of this happens in case of 'Soft Parse' and hence improves performance.
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.
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
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.
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.
TIMESTAMP – The TIMESTAMP data type allows you to store date and time data including year, month,
day, hour, minute, and second.
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.
To delete rows
DELETE FROM table_name;
--rename table
RENAME table_name TO new_name;
Oracle Constrains:
An Oracle NOT NULL constraint specifies that a column cannot contain NULL values.
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)
);
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.
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;
REGEX
select regexp_replace('fayaz&&&*%&*%$' , '\&|\*|\;|\:|\#|\$|\-|\,|\^|\~|\`|\%|\_','') from dual;
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.
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.
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;
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
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.
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.
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.
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
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
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.
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);
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.
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)
);
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;
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.
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
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
The parallel hint will open multiple parallel processes to execute the query.
The below tells the optimizer to use the default degree of parallelism determined by the initialization
parameters.
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
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;
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.
SELECT first_name,
last_name,
average_grade,
'exceptional' AS tag
FROM grade_average
WHERE average_grade>8.5;
SELECT
first_name,
last_name,
chain
FROM employee_chain;
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;
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:
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';
In this parts table, the gross_margin column is the virtual column whose values are derived from the list
price and cost 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.