Chapter 4 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10 4.11 4.12 4.13 Basic Structure Set Operations Aggregate Functions Null Values Nested Subqueries Views Complex Queries Recursion in SQL Modification of the Database Joined Relations Data-Definition Language Embedded SQL Exercises SQL 4.1 Basic Structure The Basic Structure of an SQL expression consists of three clauses: select, from and where: ① The select clause corresponds to the projection operation of the relational algebra. It is used to list the attributes desired in the result of a query. ② The from clause corresponds to the Cartesianproduct operation of the relational algebra. It lists the relations to be scanned in the evaluation of the expression. ③ The where clause corresponds to the selection predicate of the relational algebra. It consists of a predicate involving attributes of the relations that appear in the from clause. 4.1 Basic Structure A typical SQL query has the form select A1,A2,……An from r1,r2……rm where p Each Ai represents an attribute and each ri a relation. P is a predicate. The query is equivalent to the relational-algebra expression. ∏ A1,A2,……An (p(r1r2…… rm)) 4.1.1 The Select Clause SQL allows duplicates in relations as well as in the results of SQL expressions. Examples: ① Find the names of all branches in the loan relation Loan-schema=( branch-name, loan-number ,amount) select branch-name from loan loan-number branch-name amount loan branch-name L-11 Perryridge 900 Perryridge L-14 Perryridge 1500 Perryridge L-15 Mianus 2000 Mianus 4.1.1 The Select Clause ② If you want to force the elimination of duplicates, you can insert the keyword distinct after select. select distinct branch-name from loan loan-number branch-name amount loan branch-name L-11 Perryridge 900 Perryridge L-14 Perryridge 1500 Mianus L-15 Mianus 2000 4.1.1 The Select Clause ③ The asterisk symbol “” can be used to denote “all attributes”. Loan-schema=(branch-name, loan-number ,amount) select from loan select branch-name,loan-number,amount from loan loan loan-number branch-name amount loan-number branch-name amount L-11 Perryridge 900 L-11 Perryridge 900 L-14 Perryridge 1500 L-14 Perryridge 1500 L-15 Mianus 2000 L-15 Mianus 2000 4.1.1 The Select Clause ④ The select clause can also contain arithmetic expressions involving the operators,+, -, ,and /, and operating on constants or attributes of tuples. select branch-name,loan-number,amount 10 from loan loan loan loan-number branch-name amount branch-name loan-number amount L-11 Perryridge 900 Perryridge L-11 9000 L-14 Perryridge 1500 Perryridge L-14 15000 L-15 Mianus 2000 Mianus L-15 20000 4.1.2 The Where Clause SQL uses the logical connectives and, or, and not. The operands of the logical connectives can be expressions involving the comparison operators <, <=, >, >=, =, and <>. Examples: ① Find all loan numbers for loans made at the Perryride branch with loan amounts greater that $1200. Loan-schema=( branch-name, loan-number ,amount) select loan-number from loan where branch-name=“Perryridge” and amount>1200 4.1.2 The Where Clause Between: ② Find the loan number of those loans with loan amounts between $90,000 and $100,000. Loan-schema=( branch-name, loan-number ,amount) select loan-number from loan where amount between 90000 and 100000 where amount >= 90000 and amount <= 100000 Similarly, we can use the not between comparison operator. 4.1.3 The from Clause The from clause by itself defines a Cartesian product of the relations in the clause. Examples: ① For all customers who have a loan form the bank, find their names and loan number and loan amount. Borrower-schema=(customer-name, loan-number) Loan-schema=( branch-name, loan-number ,amount) select distinct customer-name, borrower.loan-number,amount from borrower, loan where borrower.loan-number=loan.loan-number 4.1.3 The from Clause borrower customer-name loan loan-number loan-number branch-name amount Hayes L-10 L-11 Perryridge 900 Johnson L-14 L-14 Perryridge 1500 Smith L-15 L-15 Mianus 2000 where borrower.loan-number=loan.loan-number customer-name borrower.loannumber Johnson L-14 L-14 Perryridge 1500 Smith L-15 L-15 Mianus 2000 loan.loan-number branch-name amount select distinct customer-name, borrower.loan-number,amount 4.1.3 The from Clause ② Find the names and loan numbers of all customers who have a loan at the Perryridge branch. Borrower-schema=(customer-name, loan-number) Loan-schema=( branch-name, loan-number ,amount) select distinct customer-name, borrower.loan-number from borrower, loan where borrower.loan-number=loan.loan-number and branch-name=“Perryridge” 4.1.4 The Rename Operation Problems: ①Two relations in the from clause may have attributes with the same name, in which case a attribute name is duplicated in the result. Example: loan-number amount loan-number amount loan loan d ②If we used an arithmetic expression in the select clause the resultant attribute does not have a name. Example: select branch-name, amount 100 namount ③ Even if a attribute name can be derived from the base relations as in the preceding example, we may want to change the attribute name in the result. 4.1.4 The Rename Operation SQL provides a way of renaming the attributes of a result relation. Example: ① If we want the attribute name loan-number to be replaced with the name loan-id. Then we can write. select distinct customer-name, borrower.loan-number as loan-id from borrower, loan where borrower.loan-number=loan.loan-number and branch-name=“Perryridge” 4.1.5 Tuple Variables Tuple variables are defined in the from clause via the use of the as clause. Tuple variables are most useful for comparing two tuples in the same relation. Example: ① Find the names of all branches that have assets greater than at least one branch located in Brooklyn. Branch-schema=(branch-name, branch-city,assets) Brighton 5100 5000 Redwood 6800 Rye 4800 … > 6200 4900 assets Brooklyn 4.1.5 Tuple Variables branch-name branch-city assets branch-name branch-city assets Brooklyn 5000 Pownal Redwood Rye 4900 Brighton Brooklyn 6200 Mianus Palo 5100 branch T > Pownal Brooklyn 5000 Redwood Rye 4900 Brighton Brooklyn 6200 Mianus Palo 5100 branch S select distinct T.branch-name from branch as T, branch as S where T.assets>S.assets and S.branch-city=“Brooklyn” 4.1.6 String Operations like: ⑴ Percent(%): The % character matches any substring. ⑵ Underscore( _ ): The _ character matches any character. Examples: ① “Perry%” matches any string beginning with “Perry”. ② “_ _ _” matches any string of exactly three characters. 4.1.6 String Operations ③ Find the names of all customers whose street address includes the substring “main” Customer-schema=(customer-name,customer-street,customer-city) select customer-name from customer where customer-street like “%main%” customer-name customer-street customer-city Pittsfield Adams Spmain customer-name Adams Brooks main Brooklyn Brooks Curry Nmainh Rye Curry Hayes Park Stamford 4.1.6 String Operations ⑶ The escape character is used immediately before a special pattern character to indicate that the special pattern character is to be treated like a normal character. Examples: using a backslash (\) as the escape character ① like “ab\%cd%” escape “\” matches all string beginning with “ab%cd” ② like “ab\\cd%” escape “\”matches all strings beginning with “ab\cd”. 4.1.7 Ordering the Display of Tuples Order by clause: desc asc Examples: ① To list in alphabetic order all customers who have a loan at the Perryridge branch. Borrower-schema=(customer-name, loan-number) Loan-schema=( branch-name, loan-number ,amount) select distinct customer-name from borrower, loan where borrower.loan-number=loan.loan-number and branch-name=“Perryridge” order by customer-name (asc) 4.1.7 Ordering the Display of Tuples Ordering can be performed on multiple attributes ② List the entire loan relation in descending order of amount. If several loans have the same amount, we order than in ascending order by loan number. Loan-schema=( branch-name, loan-number ,amount) select ﹡ from loan order by amount desc, loan-number asc loan-number branch-name amount loan-number branch-name amount L-11 Perryridge 900 L-14asc L-15 Perryridge 1500 1500 L-14 Mianus Mianus 1500 L-15 Perryridge 1500 L-11 Perryridge 900 desc 4.2 Set Operations union, intersect, except: ∪, ∩, - 1. The Union Operation Example: ① Find all customers having a loan, an account or both at the bank. customers who have a loan customers who have an account (select customer-name from depositor) union (select customer-name from borrower) Union operation automatically eliminates duplicates. If we want to retain all duplicates, we must write union all in place of union. 4.2 Set Operations 2. The Intersect Operation Example: ① Find all customers who have both a loan and an account at the bank (select customer-name from depositor) intersect (select customer-name from borrower) If we want to retain all duplicates, we must write intersect all in place of intersect. 4.2 Set Operations 3. The Except Operation Example: ① Find all customers who have an account but no loan at the bank (select customer-name from depositor) except (select customer-name from borrower) If we want to retain all duplicates, we must write except all in place of except. 4.3 Aggregate Functions 1. Aggregate functions are functions that take a collection of values as input and return a single value. SQL offers five built-in aggregate functions. Average: avg Minimum: min Maximum: max Total: sum Count: count Example: ① Find the average account balance at the Perryridge branch. account-number branch-name balance Perryridge L-16 500 select avg(balance) L-93 from account L-98 where branch-name=“Perryridge” Redwood 700 Perryridge 900 700 4.3 Aggregate Functions 2. group by clause. Examples: ①Find the average account balance at each branch. account-number branch-name balance Perryridge L-16 600 L-18 Redwood 700 L-21 Perryridge 800 L-25 Redwood 900 L-33 Perryridge 700 branch-name ebalance Perryridge 700 Redwood 800 select branch-name, avg(balance) as ebalance from account group by branch-name 4.3 Aggregate Functions ② Find the number of depositor for each branch. Depositor-schema=(customer-name, account-number) Account-schema=(branch-name, account-number, balance) select branch-name, count(distinct customer-name) from depositor,account where depositor.account-number=account.accountnumber group by branch-name 4.3 Aggregate Functions 3. having clause Example: ① we might be interested in only those branches where the average account balances is more than $750. account-number branch-name balance Perryridge L-16 600 branch-name ebalance Perryridge 700 Redwood 800 L-18 Redwood 700 L-21 Perryridge 800 ebalance> $750 L-25 Redwood 900 branch-name ebalance L-33 Perryridge 700 Redwood 800 4.3 Aggregate Functions branch-name ebalance ebalance> $750 branch-name ebalance Perryridge 700 Redwood 800 Redwood 800 select branch-name, avg(balance) from account group by branch-name having avg(balance)>750 4.3 Aggregate Functions 4. At times, we wish to treat the entire relation as a single group, in such cases, we do not use a group by clause. Example: ① Find the average balance for all account select avg(balance) customer-name customer-street customer-city Pittsfield Adams Spmain from account Brooks main 5. count (﹡) Curry Nmainh Example:① Find the Hayes Park number of tuples in the customer relation select count(﹡) from customer 4 Brooklyn Rye Stamford 4.3 Aggregate Functions 6. A where clause and a having clause appear in the same query Example:① Find the average balance for each customer who lives in Harrison and has at least three accounts. Account-schema=(branch-name, account-number, balance) Depositor-schema=(customer-name, account-number) Customer -schema=(customer-name, customer-street,customer-city) ① innerjion depositor, account, customer ② customer-city=“Harrison” (where) ③ group by depositor.customer-name ④ count(distinct depositor.account-number)>=3 (having) 4.3 Aggregate Functions ① Find the average balance for each customer who lives in Harrison. (where) ② Find the average balance for each customer who has at least three accounts. (having) select depositor.customer-name, avg(balance) from depositor, account, customer where depositor.account-number=account.account-number and depositor.customer-name=customer.customer-name and customer-city=“Harrison” group by depositor.customer-name having count(distinct depositor.account-number)>=3 4.4 Null Valus SQL allows the use of null values to indicate absence of information about the value of an attribute. We use the special keyword null in a predicate to test for a null value. Example: ① Find all loan numbers that appear in the loan relation with null value for amount. select loan-number select sum(amount) from loan from loan where amount is null 4.5 Nested Subqueries A subquery is a select-from-where expression that is nested within another query. 1. Set Membership in and not in Examples: ① Find all customers who have both a loan and an account at the bank. Borrower-schema=(customer-name, loan-number) Depositor-schema=(customer-name, account-number) select distinct customer-name from borrower where customer-name in (select customer-name from depositor) 4.5 Nested Subqueries customer-name account-number customer-name loan-number Hayes A-102 Hayes L-16 Johnson A-101 Curry depositor L-93 borrower ① select customer-name customer-name Hayes from depositor ② select distinct customer-name Curry from borrower in Hayes where customer-name in ③ select customer-name Hayes Johnson not in 4.5 Nested Subqueries ② Find all customers who have both an account and a loan at the perryridge branch. select distinct customer-name from borrower, loan where borrower.loan-number=loan.loan-number and branch-name=“perryridge” and (branch-name,customer-name) in (“perryridge” ,customer-name) (select branch-name,customer-name from depositor, account where depositor.account-number=account.account-number) 4.5 Nested Subqueries (select branch-name,customer-name from depositor, account where depositor.account-number=account.account-number) account-number branch-name balance customer-name account-number L-16 Perryridge 500 Hayes L-16 L-93 Redwood 700 Curry L-93 L-98 Mianus 900 Smith L-95 account depositor branch-name customer-name Perryridge Hayes Redwood Curry 4.5 Nested Subqueries loan-number branch-name amount customer-name loan-number L-11 Perryridge 900 Hayes L-11 L-14 Redwood 1500 Smith L-14 L-15 Mianus 800 Curry borrower L-16 loan (branch-name,customer-name) (Perryridge, Hayes) Hayes have a loan at the Perryridge branch in Hayes and Curry branch-name customer-name have a account Perryridge Hayes Redwood Curry Hayes have both an account and a loan at the perryridge branch 4.5 Nested Subqueries ③ Find all customer who do have a loan at the bank but do not have an account at the bank. select distinct customer-name from borrower where customer-name not in (select customer-name from depositor) 4.5 Nested Subqueries ④ Select the names of customers who have a loan at the bank, and whose names are neither “smith” nor “jones” select distinct customer-name from borrower where customer-name not in (“smith”, “jones”) 4.5 Nested Subqueries 2. Test for Empty Relations exist and not exist Examples: ① Find all customers who have both an account and a loan at the bank Borrower-schema=(customer-name, loan-number) Depositor-schema=(customer-name, account-number) select distinct customer-name from borrower where exists (select * from depositor Where depositor.customername=borrower.customer-name) 4.5 Nested Subqueries customer-name loan-number customer-name account-number Hayes A-102 Hayes L-16 Johnson A-101 Curry depositor L-93 borrower ① borrower(Hayes,A-102) (Johnson,A-101) customer-name ② (select * from depositor Where depositor.customer-name=‘Hayes’) ③ where exists(‘Hayes’, ‘L-16’) True ④ select customer-name form (Hayes,A-102) Hayes 4.5 Nested Subqueries ② Find all customers who have an account at all the branches located in brooklyn. Brighton Brighton contain Downtown Smith brighton downtown Downtown B except curry brighton all the branches in brooklyn relation A contains relation B not exists(B except A) brighton A downtown Redwood … smith Null not exists smith true 4.5 Nested Subqueries Depositor-schema=(customer-name, account-number) Account-schema=(branch-name, account-number, balance) Branch-schema=(branch-name, branch-city,assets) not exists Brighton Downtown ( (select branch-name B Brighton A Downtown smith from branch B where branch-city=“brooklyn”) except (select customer-name ,branch-name from depositor as T, account as R where T.account-number=R.account-number) ) A 4.5 Nested Subqueries Depositor-schema=(customer-name, account-number) Account-schema=(branch-name, account-number, balance) select distinct S.customer-name from depositor as S Where not exists ((select branch-name from branch where branch-city=“brooklyn”) except (select R.branch-name from depositor as T, account as R where T.account-number=R.account-number and S.customer-name=T.customer-name)) 4.5 Nested Subqueries ③ find the names of all students who have not chosen all courses.(who choose all courses?) S-schema=(sno,sname,ssex,sage) PK =sno C-schema=(cno,cname,teacher) PK=cno SC-schema=(sno,cno,score) PK =(sno,cno) Smith c-11 C-10 C-11 all the courses number not contain curry c-11 c-10 … Smith 4.5 Nested Subqueries S-schema=(sno,sname,ssex,sage) C-schema=(cno,cname,teacher) SC-schema=(sno,cno,score) PK =sno PK=cno PK =(sno,cno) select sname from s where exists false (select * true from c false where not exists true (select * from sc where sc.cno=c.cno and sc.sno=s.sno)) 4.5 Nested Subqueries ④ find the names of all students who have chosen the courses including one course which the NO.1 student has chosen at lease. S-schema=(sno,sname,ssex,sage) PK =sno C-schema=(cno,cname,teacher) PK=cno SC-schema=(sno,cno,score) PK =(sno,cno) Smith c-11 C-10 C-11 NO.1 contain Curry c-10 c-11 Smith Curry … 4.5 Nested Subqueries S-schema=(sno,sname,ssex,sage) PK =sno C-schema=(cno,cname,teacher) PK=cno SC-schema=(sno,cno,score) PK =(sno,cno) sx sno cno score sy sno cno score select sname from s No.1 C-10 90 No.1 C-10 90 true where exists No.1 C-11 89 No.1 C-11 89 false (select * No.2 C-10 78 No.2 C-10 78 from sc as sx No.2 C-11 86 No.2 C-11 86 where sno=“NO.1” No.3 C-11 89 true and exists (select * No.3 C-11 89 from sc as sy false where sy.sno=s.sno and sx.cno=sy.cno)) 4.5 Nested Subqueries ⑤ Find the names of all students who choose the courses include all courses which NO.1 students has chosen at least. sx sno cno score sy sno cno score select sname No.1 C-10 90 No.1 C-10 90 from s true No.1 C-11 89 No.1 C-11 89 where not exists false (select * No.2 C-10 78 No.2 C-10 78 from sc as sx No.2 C-11 86 No.2 C-11 86 where sno=“NO.1” No.3 C-11 89 No.3 C-11 89 false and not exists (select * true from sc as sy where sy.sno=s.sno and sx.cno=sy.cno)) 4.5 Nested Subqueries ⑥ Find the names of all students who have chosen the courses not including all courses which NO.1 students has chosen. exists not exists 4.5 Nested Subqueries 3. Set comparison >some ==“greater than at least one” ( any ) Examples: ① Find the names of all branches that have assets greater than those of at least one branch located in brooklyn. Branch-schema=(branch-name, branch-city,assets) select distinct T.branch-name from branch as T, branch as S where T.assets>S.assets and S.branch-city=“Brooklyn” 4.5 Nested Subqueries 1350 (Bighton) 1500 select branch-name 1550 (Mianus) 1600 from branch 1900 where assets > some(select assets ? > ……. (……….) assets (brooklyn) >some >min() =some in from branch where branch-city=“brooklyn”) ② Find the names of all branches that have assets greater than that of each branch in brooklyn. >some >all <>all not in 4.5 Nested Subqueries ③ Find the branch that has the highest average balance Account-schema=(account-number,branch-name,balance) 1350 (Bighton) avg(balance) 1900 (Mianus) ……. (……….) select branch-name from account group by branch-name 1500 >= ? 1600 >=all max() 1900 avg(balance) all branchs having avg(balance) >=all (select avg(balance) from account group by branch-name) 4.5 Nested Subqueries 4. Test for the Absence of Duplicate Tuples unique construct Examples: ① Find all customers who have only one account at the perryridge branch. select T.customer-name from depositor as T where unique(select R.customer-name from account,depositor as R where T.customer-name=R.customer-name and R.account-number=account.account-number and account.branch-name=“perryridge”) 4.5 Nested Subqueries ② Find all customers who have at least two accounts at the perryridge branch. unique not unique 4.6 views The form of the create view command is: create view v as <query expression> Examples: ① consider the view consisting of branch names and the names of customers who have either an account or a loan at that branch. Assume that we want this view to be called all-customer. create view all-customer as (select branch-name, customer-name from depositor, account where depositor.account-number=account.account-number) union (select branch-name, customer-name from borrower, loan where borrower.loan-number=loan.loan-number) 4.6 views ② The attribute names of a view can be specified explicitly as follows: create view branch-total-loan(branch-name,total-loan) as select branch-name, sum(amount) from loan group by branch-name ③ Using the view all-customer, we can find all customers of the perryridge branch. select customer-name from all-customer where branch-name=“perryridge” 4.7 Complex Queries Derived Relations: Result relation should be given a name, and the attributes can be renames. Examples: ① Find the average account balance of those branches where the average account balance is greater than$1200 Account-schema=(branch-name, account-number, balance) select branch-name, avg-balance from (select branch-name, avg(balance) from account group by branch-name) as result(branch-name, avg-balance) where avg-balance > 1200 4.7 Complex Queries ② Find the branch name which has the largest sum of account balance in the bank. select max(tot-balance) from (select branch-name, sum(balance) from account group by branch-name) as branch-total(branchname, tot-balance) 4.7 Complex Queries The with clause Examples: ① Find the account number which has the largest account balance in the bank. with max-balance(value) as select max(balance) from account select account-number from account,max-balance where account.balance=max-balance.value ② Find all branches where the total account deposits less than the average of the total account deposits at all branches. 4.7 Complex Queries with branch-total(branch-name,value) as select branch-name,sum(balance) from account group by branch-name with branch-total-avg(value) as select avg(value) from branch-total select branch-name from branch-total,branch-total-avg where branch-total.value>=branch-total-avg.value 4.8 Recursion in SQL With recursive clause: Example: ① suppose the relation manager has a attributes emp and mgr. We can find every pair(X,Y)such that X is directly or indirectly managed by Y. with recursive empl(emp,mgr) as ( mgr emp select emp, mgr Alon Jak from manager union Jak Kat select emp,empl.mgr Met Fin from manager,empl Fin Lat where manager.mgr=empl.emp) select * Lat Gut from empl 4.9 Modification of the Database 1. Deletion delete from r where p (relation) (predicate) Notice: We can delete only whole tuples; we can’t delete values on only particular attributes. Examples: ① delete all smith’s account records delete from depositor where customer-name=“smith” ② delete all loans with loan amounts between $1300 and $1500 delete from loan where amount between 1300 and 1500 4.9 Modification of the Database ③ delete all accounts at every branch located in perryridge. delete from account where branch-name in (select branch-name from branch where branch-city=“perryridge”) ④ delete the records of all accounts with balances below the average at the bank. delete from account where balance (select avg(balance) from account) 4.9 Modification of the Database 2. Insertion To insert data into a relation, we either specify a tuple to be inserted or write a query whose result is a set of tuples to be inserted. Examples: ① Suppose that we wish to insert the fact that there is an account A-9732 at the perryridge branch and that is has a balance of $1200 insert into account values(“perryridge”, “A-9732”,1200) or insert into account(account-number,branch-name,balance) values(“A-9732”, “perryridge”,1200) 4.9 Modification of the Database ② suppose that we want to provide as a gift for all loan customers of the perryride branch, a new $200 savings account for each loan account they have.let the loan number serve as the account number for the savings account. insert into account select branch-name, loan-number, 200 from loan where branch-name=“perryridge” We also need to add tuples to the depositor relation. 4.9 Modification of the Database Insert into depositor select customer-name, loan-number from borrower, loan where borrower.loan-number=loan.number and branch-name=“perryridge” Problems: ① insert into account select * from accont ② insert into account values(null, “A-401”, 1200) select account-number from account where branch-name=“perryridge” 4.9 Modification of the Database 3. Updates In certain situations, we may wish to change a value in a tuple without changing all values in the tuple. Examples: ① account with balance over $10,000 receive 6 percent interest, whereas all other receive a percent. update account set balance=balance*1.06 where balance>10000 update account set balance=balance*1.05 where balance<=10000 4.9 Modification of the Database ② pay 5 percent interest on accounts whose balance is greater than average. update account set balance=balance*1.05 where balance> (select avg(balance) form account) Case construct: update account set balance= case when balance<=10000 then balance*1.05 esle balance*1.06 end 4.9 Modification of the Database 4. Update of a view Example: create view branch-loan as select branch-name, loan-number from loan insert into branch-loan values(“perryridge”, “L-307”) * A modification is permitted through a view only if the view in question is defined in terms of one relation of the actual relational database---that is, of the logical-level database. 4.10 Joined Relations SQL provide various mechanisms for joining relations, including condition joins, natural joins and various forms of outer joins. (from clause) 1. Inner join Example: branchname loannumber amount customer Loan-name number Downtown L-170 3000 Jones L-170 Redwood L-230 4000 Smith L-230 Perryridge L-260 loan 1700 Hayes L-155 borrower 4.10 Joined Relations 1. Inner join loan inner join borrower on loan.loan-number=borrower.loan-number branchname loanamount customer number -name Loannumber Downtown L-170 3000 Jones L-170 Redwood L-230 4000 Smith L-230 the attributes of the result consist of the attributes of the lefthand-side relation followed by the attributes of the right-hand-side relation. Using as loan inner join borrower on loan.loan-number=borrower.loan-number as lb ( branch, loan-number, amount, cust, cust-loan-num) 4.10 Joined Relations 2. Left outer join loan left outer join borrower on loan.loan-number=borrower.loan-number Steps: ① compute the inner join ② for every tuple t in the left-hand-side relation loan that did not match any tuple in the right-hand-side relation borrower in the inner join, a tuple r is added to the result of the join as follows. The attributes of tuple r that are derived from the left-hand-side relation are filled with null values. branchname loannumber amount customer -name Loannumber Downtown L-170 3000 Jones L-170 Redwood L-230 4000 Smith L-230 Perryridge L-260 1700 null null 4.10 Joined Relations 3. Natural join loan natural inner join borrower branchname loanamount customer number -name Downtown L-170 3000 Jones Redwood L-230 4000 Smith Notices: The attributes loan-number appears only once in the result of the natural join. 4.10 Joined Relations Join type and conditions ① join condition: define which tuples in the two relations match, and what attributes are present in the result of the join. (natural; on<predicate>; using<A1,A2……An>) ② join type: define how tuples in each relation that do not match any tuple in the other relation are treated. (inner join, left outer join, right outer join, full outer join) Examples: ① loan natural right outer join borrower branch-name loannumber amount customer -name Downtown L-170 3000 Jones Redwood L-230 4000 Smith null L-155 null Hayes 4.10 Joined Relations ② loan full outer join borrower using (loan-number) branchname loannumber amount customer -name Downtown L-170 3000 Jones Redwood L-230 4000 Smith Perryridge L-260 1700 null L-155 null Hayes null 4.10 Joined Relations ③ find all customers who have an account but no loan at the bank. select d-CN from (depositor left join borrower on depositor.customer-name=borrower.customer-name as db1(d-CN, account-number, b-CN, loan-number) where b-CN is null ④ find all customers who have either an account or a loan at the bank. select customer-name from (depositor natural full outer join borrower) where account-number is null or loan-number is null 4.11 Data-Definition Language The set of relations in a database must be specified to the system by means of a data definition language(DDL) Specification function: ① the schema for each relation ② the domain of values associated with each attribute ③ the integrity constraints ④ the set of indices to be maintained for each relation ⑤ the security and authorization information for each relation ⑥ the physical storage structure of each relation on disk 4.11 Data-Definition Language Domain Types in SQL Domain types: char(n) varchar(n) int smallint numeric(p,d) real time interval float(n) date a particular case where it is essential to prohibit null values is in the primary key of a relation schema. create domain clause create domain person-name char(20) 4.11 Data-Definition Language Schema Definition in SQL create table command: create table r (A1D1, A2D2……AnDn, <integrity-constrant1>, …… <integrity-constrantk>) The allowed integrity constraints include: primary key (Aj1,Aj2……Ajm) nonnull unique and check(p) 4.11 Data-Definition Language check clause: Examples: ① create table student (name char(15) not null student-id char(10) not null degree-level char(15) not null primary key (student-id) check(degree-level in(“bachelors”, “masters”, “doctorate”))) ① check (branch-name in (select branch-name from branch)) 4.11 Data-Definition Language Remove a relation: drop table r ( delete from r ) Add attributes to an existing relation: alter table r add AD Drop attributes from a relation: alter table r drop A 4.12 Embedded SQL Most SQL products allow SQL statements to be executed both directly and as part of an application program can typically be written in a variety of host language. The fundamental principle underlying embedded SQL, which we refer to as the dual mode principle, is that any SQL statement that can be used interactively can also be used in an application program. Points: ① Embedded SQL statement are prefixed by EXEC SQL, to distinguish them from statement of the host language, and are terminated by a special terminator symbol. 4.12 Embedded SQL ② An executable SQL statement can appear wherever an executable host statement can appear. Embedded SQL includes some statements that are purely declarative, not executable. ③ SQL statements can include references to host variable; such references must include a colon prefix to distinguish them from SQL column names. ④ All host variable referenced in SQL statements must be declared . Within an embedded SQL declare section, which is delimited by the BEGIN and EDN DECLARE SECTION statement. 4.12 Embedded SQL ⑤ Every program containing embedded SQL statements must include a host variable called SQLSTATE. ⑥ Host variable must have a data type appropriate to the uses to which they are put. Host variables and SQL columns can have the same name. Problem: Operations retrieve may rows, not just one, and host languages are generally not equipped to handle the retrieved of more than one row at a time. 4.12 Embedded SQL Solution: cursors A cursor is a special kind of SQL object that applies to embedded SQL only. It consists essentially of a kind of pointer that can be used to run through a collection of rows, pointing to each of the rows in turn and thereby providing address ability to those rows one at a time. 4.12 Embedded SQL Example: EXEC SQL DECLARE C SURSOR FOR select customer-name, customer-city from depositor, customer, account where depositor.customer-name=customer.customer-name and account.account-number=depositor.account-number and account.balance>:amount END-EXEC 4.12 Embedded SQL EXEC SQL OPEN C Do for all depositor rows accessible via c END-EXEC EXEC SQL FETCH C INTO :cn, :cc END-EXEC EXEC SQL CLOSE C END-EXEC 4.12 Embedded SQL ① The variable c in the preceding expression is called a cursor for the query. The statement “DECLARE C CURSOR…” defines a cursor called c. ② DECLARECURSOR is a purely declarative statement, not executable. The expression is evaluated when the cursor is opened. ③ The statement “FETCH C INTO…” is then used to retrieve rows one at a time from the resulting set, assigning retrieved values to host variables in accordance with the specifications of the INTO clause in that statement. 4.12 Embedded SQL ④ Since there will be many rows in the result set, the FEICH with normally appear within a loop; the loop will be repeated so long as there are more rows still to come in that result set. On exit from the loop, cursor c is closed. ⑤ There executable statement are provided to operate on cursors: OPEN, FETCH and CLOSE ⅰEXEC SQL OPEN<cursor name> ⅱEXEC SQL FETCH<cursor name> INTO <host variable reference commalist> ⅲEXEC SQL CLOSE<cursor name> 4.12 Embedded SQL Example: using the suppliers-parts-projects database, write a program with embedded SQL statement to list all supplier rows, in supplier number order. Each supplier row should be immediately followed in the listing by all project rows for projects supplied by that supplier, in project number order. Note that there might be some suppliers who supply no projects at all. S={SNO, SNAME, STATUS, CITY} J={JNO, JNAME, CITY} SPJ={JNO,SNO,PNO,QUENTITY} 4.12 Embedded SQL First we define two cursors, CS and CJ. # define no_more_tuples!(strcmp(SQLSTATE,”02000”)) void pinfo(){ EXEC SQL BEGIN DECLARE SECTION; int SNO, JNO; char SNAME[20], SCITY[50], STATUS[12], JNAME[20]; char JCITY[50], SQLSTATE[6]; EXEC SQL END DECLARE SECTION; EXEC SQL DECLARE CS SURSOR FOR SELECT SNO, SNAME, STATUS, CITY FROM S ORDER BY SNO; 4.12 Embedded SQL EXEC SQL DECLARE CJ SURSOR FOR SELECT JNO, JNAME, CITY FROM J WHERE JNO IN (SELECT SPJ.JNO FROM SPJ WHERE SPJ.SNO=:SNO) ORDER BY JNO; EXEC SQL OPEN CS; while(1){ EXEC SQL TETCH CS INTO :SNO, :SNAME, :STATUS,:SCITY; if(no_more_tuples) break; printf(“%d,%c,%c,%c”,SNO,SNAME,STATUS,SCITY); 4.12 Embedded SQL EXEC SQL OPEN CJ; while(1){ EXEC SQL TETCH CJ INTO JNO,JNAME,JCITY; if(no_more_tuples) break; printf(“%d,%c,%c”,JNO,JNAME,JCITY); } EXEC SQL CLOSE CJ; } EXEC SQL CLOSE CS; } 4.12 Embedded SQL Dynamic SQL The two principal dynamic statements are PREPARE and EXECUTE. Example: DCL SQLSOURCE CHAR VARYING(65000) SQLSOURE=“DELETE FROM loan WHERE amount<300”; EXEC SQL PREPARE SQLPREPPED FROM: SQLSOURCE; EXEC SQL ECECUTE SQLPREPPED; Exercises: ① Relational Model: Relation S(S#, SNAME, CITY) KEY=S# Relation P(P#, PNAME, COLOR, WEIGHT) KEY=P# Relation J(J#, JNAME, CITY) KEY=J# Relation SPJ(S#, P#, J#, QTY) KEY=S# P# J# Consider the relational model, for each of the following queries, given an expression in the relational algebra, the tuple-relationalcalculus, the domain-relational-calculus and the SQL: a. Find the suppliers’ numbers s# of all suppliers who offer the parts to both projects J1 and J2. b. Find the suppliers’ numbers s# of all suppliers who offer the parts to any projects of either ShangHai or BeiJing. Exercises: c. Find the suppliers’ numbers s# of all suppliers of ShangHai who offer the parts to the projects of their own places. d. Find the suppliers’ numbers s# of all suppliers of BeiJing who never offer the red parts. e. Find the project numbers J# which use the parts offered by S1 at least. f. Find the names of all suppliers who offer all parts. g. Find the suppliers’ numbers s# of all suppliers who offer the all parts that S1 offered.