SQL conventions Writing SQL Statements: conventions vs. requirements We try to write SQL statements so they are readable. That is why we try to put SELECT, FROM, WHERE on newlines. Caps are not required for keywords. Table aliases are usually just a single letter. Fully qualified column names are required if ambiguous. Access will complain. SELECT * FROM Employee e INNER JOIN Timecard t ON e.ssn=t.ssn; is the same as: SELECT * FROM Employee e INNER JOIN Timecard t ON e.ssn=t.ssn;
More SQL (equi-)joins An equi-join is a join where the constraint is on two columns matching (or being equal). A natural join is an equi-join when the columns share the same name in both tables. Both are also called “normal joins” and the INNER JOIN keywords are used for both. But as seen you could also use a WHERE clause. This is by far the most common type of join used.
Inner Join A regular INNER JOIN in with SQL can be written as follows: SELECT * FROM Employee e, Timecard t WHERE e.ssn=t.ssn; or SELECT * FROM Employee e INNER JOIN Timecard t ON e.ssn=t.ssn; e.ssnlastNamefirstNamet.ssndatestartTimeendTimestoreIdpaid UnoJane /14/20028:15:00 AM12:00:00 PM3Yes UnoJane /16/20028:15:00 AM12:00:00 PM3Yes ToulouseJie /14/20028:15:00 AM12:00:00 PM3Yes ThreatAyisha /3/200210:00:00 AM2:00:00 PM5Yes ThreatAyisha /23/20022:00:00 PM10:00:00 PM5Yes ThreatAyisha /21/20023:00:00 PM7:00:00 PM5Yes ThreatAyisha /3/20023:00:00 PM7:00:00 PM3Yes
Why use INNER JOIN SELECT COUNT(*) AS [Count of Cartesian] FROM Employee, Timecard; Count of Cartesian 35 With the INNER JOIN command an ON clause is required so you won’t accidentally get a cross- product instead of a join. This is very likely going to happen to you at some point if you don’t use INNER JOIN.
Other types of joins Self join is a table joined with itself. Recall lab 4 (office). An employee had a mentor. To get all the employees and their mentors we’d use a self-join SELECT e.SSN, e.FNAME, e.LNAME, e.MENTOR, m.FNAME FROM EMPLOYEE AS e INNER JOIN EMPLOYEE AS m ON e.MENTOR=m.SSN; SSNFNAMELNAMEMENTOR BillHomer JoeSmith XenaCreek SSNe.FNAMELNAMEMENTORm.FNAME BillHomer Joe XenaCreek Joe
Outer joins Notice that we only got 2 results. Why? Because Joe does not have a mentor. That is, the MENTOR field for Joe is NULL. Suppose we want to list all the employees, including those that don’t have a mentor. That is what an outer join is for. Rows in one table without matching rows in the other table can be included in the results. LEFT OUTER JOIN includes those in the left without matches RIGHT OUTER JOIN includes those in the right without matches FULL OUTER JOIN (both, but not in Access -> use union instead)
LEFT OUTER self-join SELECT e.SSN, e.FNAME, e.LNAME, e.MENTOR, m.FNAME FROM EMPLOYEE AS e LEFT JOIN EMPLOYEE AS m ON e.MENTOR=m.SSN; SSNe.FNAMELNAMEMENTORm.FNAME JoeSmith BillHomer Joe XenaCreek Joe
RIGHT OUTER self-join SELECT e.SSN, e.FNAME, e.LNAME, e.MENTOR, m.FNAME FROM EMPLOYEE AS e RIGHT JOIN EMPLOYEE AS m ON e.MENTOR=m.SSN; SSNe.FNAMELNAMEMENTORm.FNAME Bill BillHomer Joe XenaCreek Joe Xena What the heck does this mean?
Cross Product e.SSNe.FNAMEe.LNAMEe.MENTORm.SSNm.FNAMEm.LNAMEm.MENTOR JoeSmith JoeSmith BillHomer JoeSmith XenaCreek JoeSmith JoeSmith BillHomer BillHomer BillHomer XenaCreek BillHomer JoeSmith XenaCreek BillHomer XenaCreek XenaCreek XenaCreek SELECT * FROM EMPLOYEE e, EMPLOYEE m;
ssnlastNamefirstName UnoJane ToulouseJie ThreatAyisha FortuneJulian FivozinskyBruce EMPLOYEE ssndatestartTimeendTimestoreIdpaid /14/20028:15:00 AM12:00:00 PM3Yes /16/20028:15:00 AM12:00:00 PM3Yes /14/20028:15:00 AM12:00:00 PM3Yes /3/200210:00:00 AM2:00:00 PM5Yes /3/20023:00:00 PM7:00:00 PM3Yes /23/20022:00:00 PM10:00:00 PM5Yes /21/20023:00:00 PM7:00:00 PM5Yes TIMECARD storeIdstreetcitystatezipcodemanager Liberty Rd.ApopkaFL N. Monroe St.ApopkaFL STORE
Multi-table joins Let’s look at all the timecards for employees. SELECT e.firstName, e.lastName, t.date, t.startTime FROM Timecard t INNER JOIN Employee e ON t.ssn=e.ssn; firstNamelastNamedatestartTime JaneUno1/14/20028:15:00 AM JaneUno1/16/20028:15:00 AM JieToulouse1/14/20028:15:00 AM AyishaThreat1/3/200210:00:00 AM AyishaThreat2/23/20022:00:00 PM AyishaThreat3/21/20023:00:00 PM AyishaThreat1/3/20023:00:00 PM
3 table join SELECT e.firstName, e.lastName, t.date, t.startTime, s.street AS [Store Street], s.city AS [Store City] FROM Store s INNER JOIN (Timecard t INNER JOIN Employee e ON t.ssn=e.ssn) ON t.storeId=s.storeId; firstNamelastNamedatestartTimeStore StreetStore City JaneUno1/14/20028:15:00 AM2010 Liberty Rd.Apopka JaneUno1/16/20028:15:00 AM2010 Liberty Rd.Apopka JieToulouse1/14/20028:15:00 AM2010 Liberty Rd.Apopka AyishaThreat1/3/200210:00:00 AM1004 N. Monroe St.Apopka AyishaThreat2/23/20022:00:00 PM1004 N. Monroe St.Apopka AyishaThreat3/21/20023:00:00 PM1004 N. Monroe St.Apopka AyishaThreat1/3/20023:00:00 PM2010 Liberty Rd.Apopka
Arrangement of joins What happens if I rearrange the joins? SELECT e.firstName, e.lastName, t.date, t.startTime, s.street AS [Store Street], s.city AS [Store City] FROM Employee e INNER JOIN (Timecard t INNER JOIN Store s ON t.storeId=s.storeId) ON e.ssn=t.ssn; firstNamelastNamedatestartTimeStore StreetStore City JaneUno1/14/20028:15:00 AM2010 Liberty Rd.Apopka JaneUno1/16/20028:15:00 AM2010 Liberty Rd.Apopka JieToulouse1/14/20028:15:00 AM2010 Liberty Rd.Apopka AyishaThreat1/3/200210:00:00 AM1004 N. Monroe St.Apopka AyishaThreat2/23/20022:00:00 PM1004 N. Monroe St.Apopka AyishaThreat3/21/20023:00:00 PM1004 N. Monroe St.Apopka AyishaThreat1/3/20023:00:00 PM2010 Liberty Rd.Apopka
Non-equi (theta) joins We are not limited to doing equi-joins on foreign key – primary key columns. You can also do joins based on comparison operators >, >=, These are rare. SELECT s.storeId, w.ssn FROM Store s INNER JOIN WorksIn w ON s.storeId <> w.storeId; storeIdssn