sql
sql
Concepts/Facts
DDL
Create
● create table Client (
clientId int,
name varchar2(15),
hkid char(10),
address varchar2(20),
district varchar2(20));
Alter
alter table Client
add postalCode int;
Drop
drop table Client;
Check
Create table Loan (
loanNo char(5) primary key,
amount number(8,2) check (amount>=1000 and amount<=100000),
year char(4),
branchName varchar2(15) not null);
Insert
Insert into Account (accountNo, branchName, balance) values ('A-734', 'Pacific Place',
1200);
Update
update
4
Account
set
balance=50000
where
accountNo= ‘A-733';
Not null
create table Client (
clientId int primary key,
name varchar2(15) not null,
hkid char(10) not null,
address varchar2(20) not null,
district varchar2(20) not null,
unique (hkid));
Unique
create table Client (
clientId int primary key,
name varchar2(15) not null,
hkid char(10) not null,
address varchar2(20) not null,
district varchar2(20) not null,
unique (hkid));
DML (Part 1)
Like
REGEXP_LIKE
Character Description
select name
from Client
where regexp_like (name, '^Ste(v|ph)en');
=> Steven or Stephen (i.e., the name begins with ‘Ste’ followed by either ‘v’ or ‘ph’ followed by ‘en’
select name
from Client
where regexp_like (name, '([aeiou])\1', 'i');
Fetch
select name, rating
from Client
order by rating, name
fetch first 3 rows only;
=>Find the name and credit rating of the three clients
OFFSET
select distinct rating
from Client
order by rating desc nulls last
offset 2 rows
fetch next 1 row only;
=>Find the third highest credit rating
places
DML (Part 2)
Example:
Group By / Having
select clientId
from Depositor D, Account A
8
where D.accountNo=A.accountNo
and branchName='Star House'
group by clientId
having count(*)=1;
=>Find the id of clients who have only one account at the Star House branch.
Nested Subquery
=>Find the client id, name and credit rating of all clients with
the third highest credit rating. Order the result by client
name ascending.
IN
group by branchName);
=> Find, for each branch, the branch name, client id, client name, and client account
balance of the clients with the largest account balance.
Some
Select branchName
from Branch
where assets >some (select assets
from Branch
where district='Yau Tsim Mong);
=>Find the name of the branches that have greater assets than
some (i.e., at least one) branch located in Yau Tsim Mong
district.
All
select branchName
from Branch
where assets >all (select assets
from Branch
where district='Yau Tsim Mong ');
Exist
select clientId
from Depositor D
where exists (select *
from Borrower B
where D.clientId=B.clientId);
from Depositor D
where not exists (select *
from Borrower B
where D.clientId=B.clientId);
=> Find the id of clients who have an account, but do not have
a loan
SUBQUERY
=> Find the name and average balance of the branches whose
average balance is greater than the average account balance
With
=> Find the name and average balance of branches with the maximum average account
balance.
11
DML (Part 3)
Partition by
Select accountNo, balance, branchName,
sum(balance) over (partition by branchName) as totalBranchBalance
from Account;
=>Find the account information for each account as well as the total balance for the
account's branch.
Order by
Rank
=>For each bank branch find the branch name, its assets and
its rank among all bank branches based on its assets.
Rank + Partition by
=>Find the branch name, account number, balance and rank of the accounts in each
branch based on the account's balance. Order the result by branch name and rank
Dense_Rank
The rank function gives the same rank to all tuples that have
equal value on the order by attributes.
– E.g., if two branches have the same highest asset value, both would
get rank 1.
This results in "gaps" in the ranking
– E.g., if two branches have the top rank of 1, then the next rank
would be 3, not 2.
The dense_rank function eliminates gaps in the ordering; ties still
get the same rank.
ntile
=>Find the branch name, assets and the quartile into which
each branch falls based on its assets.
Listagg
select district, listagg(name, ', ') within group (order by name) clients
from Client
13
group by district
order by district;
=>Find, for each district, the name of the clients in the district.
Order the result first by district ascending and and then by
names ascending.
=>Find, for each loan in 2023, the loan number, loan amount,
branch name and the amount of each of the loans given in
the same year at the same branch. Order the result by the
loan amount.
Windowing
select year,
avg(yearLoanTotal) over (order by year rows 2 preceding)
as movingAverageYearLoanTotal
from (select year, sum(amount) as yearLoanTotal
from Loan
group by year);
=>For each year, find the average total loan amounts for the year and the previous two-
year period. (Calculate 3 yr for each yr)
select year,
avg(yearLoanTotal) over (order by year rows
between unbounded preceding and 1 following)
as movingAverageYearLoanTotal
from (select year, sum(amount) as yearLoanTotal
14
from Loan
group by year);
=>For each year, find the average total loan amounts for the
year, for all previous years and for the following year.
DDL
Complex Insertion
Complex Delete
Complex Update
update Account
set balance = case
when balance<=10000 then balance*1.05
else balance*1.06
end;
View
=> Create a view of the Loan relation that hides the amount.
View Update
Aassertion
=> The sum of all loan amounts for each branch must be less
than the sum of all account balances at the branch.
Trigger
select *
from SaleOrder
pivot (sum(quantity)
for subject in ('Art', 'Business', 'Travel'))
order by format, language;
Cube
=> Rollup the SaleOrder relation by format only and by both subject and language.
Order the result first by format, then by subject and finally by language.
select (case when grouping(format)=1 then 'all' else format end) as format,
(case when grouping(subject)=1 then 'all' else subject end) as subject,
(case when grouping(language)=1 then 'all' else language end) as language,
sum(quantity) as total
from SaleOrder
group by rollup(format, subject, language);
select (case when grouping(format)=1 then 'all' else format end) as format,
(case when grouping(subject)=1 then 'all' else subject end) as subject,
(case when grouping(language)=1 then 'all' else language end ) as language,
sum(quantity) as total
from SaleOrder
group by cube(format, subject, language);
18
JSON
json_object
Construct an SQL query to create a JSON object for each sailor in the
Sailor relation containing as fields all attributes of the Sailor relation
select json_object(
'sailorId' value sailorId,
'sName' value sName,
'hkid' value hkid,
'rating' value rating,
'age' value age)
from Sailor;
json_object + array
Construct an SQL query to create a JSON object for each sailor
who has reserved a boat containing as fields the sailor id, name
and an array named 'reservations' where the array elements are
the id, name and color of each boat that the sailor reserved.
select json_object(
'sailorId' value sailorId,
'sName' value sName,
'reservations' value json_array(boatId, bName, color))
from Sailor natural join Reserves natural join Boat;
json_object + arragg
Construct an SQL query to create a JSON object for each
sailor who has reserved a boat containing as fields the sailor
id, name and an array named 'reservations’ where the array
elements are the ids of the boats that the sailor reserved.
select json_object(
'sailorId' value sailorId,
'sName' value sName,
'reservations' value json_arrayagg(boatId))
from Sailor natural join Reserves
group by sailorId, sName;
19
select json_object(
'sailorId' value sailorId,
'sName' value sName,
'reservations' value json_arrayagg(json_object('boatId' value boatId,
'bName' value bName)))
from Sailor natural join Reserves natural join Boat
group by sailorId, sName;
Absent on null
Construct an SQL query to create a JSON object for each sailor in the
Sailor relation containing as fields all the attributes of Sailor and an
object named 'reservations' where each object contains as fields the
id, name and color of the boats that the sailor reserved. If a sailor has
not reserved any boats, then the 'reservations' field should be absent.
[ Method 1 ]
select json_object(
'sailorId' value sailorId,
'sName' value sName,
'hkid' value hkid,
'rating' value rating,
'age' value age,
'reservations' value json_arrayagg(json_object('boatId' value boatId,
'bName' value bName,
'color' value color
absent on null)))
from Sailor natural left outer join (Reserves natural join Boat)
group by sailorId, sName, hkid, rating, age;
[ Method 2 ]
select json_object(
'sailorId' value sailorId,
'sName' value sName,
'hkid' value hkid,
'rating' value rating,
'age' value age,
'reservations' value (select json_arrayagg(json_object('boatId' value B.boatId,
'bName' value bName,
'color' value color))
20
Absent on null
Construct an SQL query to create a JSON object for each student
containing as fields the student id, name (as a single field shown as 'last
name, first name') and an array named 'courses' where the array elements
are the course ids of the courses in which the student is enrolled. The
'courses' array should be absent if a student is not enrolled in any course.
Order the students by last name ascending.
select json_object(
'studentId' value studentId,
'name' value lastName || ', ' || firstName,
'courses' value json_arrayagg(courseId absent on null)) as students
from Student natural left outer join EnrollsIn
group by studentId, firstName, lastName
order by lastName;