NURS6803 Clinical DB Design Katherine Sward, PhD, RN Even more SQL… NURS6803 Clinical DB Design Katherine Sward, PhD, RN 1
Union queries Up to this point we joined tables horizontally, with additional columns select demog.pt_id, name, rbc, wbc from demog, blood where demog.pt_id = blood.pt_id pt_id name rbc wbc 10 Brown, Mike 5.62 9.4 102 Costner, Kevin 3.32 16 3.55 12 103 Cole, Nat-King 4.39 5.8 3.36 3.7 104 Mason, Perry 4.05 7.5 105 Go, King-Fung 5 109 Bond, James 4.24
Union queries student (unid, lastname, firstname, email, major) faculty (unid, lastname, firstname, email, department) Get a list of unid, name, and email for all students and faculty Process: create a query for each table, then paste the results together vertically into a single list that is a UNION query
Union queries SELECT unid, lastname, firstname email, ‘student’ as PersonType FROM students UNION SELECT unid, lastname, firstname, email, ‘faculty’ as PersonType FROM faculty; unid lastname firstname email PersonType u00123456789 Smith Sam sam@somewhere.com student u00123455555 Jones Joe joe@somewhere.com u00123457777 Anders Sally sally@somewhere.com u00123458888 Williams Greg greg@somewhere.com faculty Dodge Kathy kathy@somewhere.com
Union queries Queries must be “Union compatible” return same structure – same number of columns, matching data types (convert if necessary) columns should conceptually match
Self join Recursive relationship: there is a relationship between different rows in the same table
Table data employeeID name dateOfHire managerID u0000001 Bossman, Bob 1/1/2005 u0000002 Overseer, Susie 1/2/2005 u0000003 Worker, William 2/1/2005 u0000004 Smith, Sam u0000005 Jones, Jenny 8/15/2010 u0000006 Little, Larry 8/21/2011 u0000007 Mann, Macho 7/17/2006 u0000008 Pipsqueak, Pippy 4/15/2007 u0000009 Doer, Danny 6/6/2006 u0000010 Jones, Jeff 2/8/2009
Self join Who are Susie’s employees? or Show the ID and name for an employee, and the name of the employee’s manager
employeeID name dateOfHire managerID u0000001 Bossman, Bob 1/1/2005 u0000002 Overseer, Susie 1/2/2005 u0000003 Worker, William 2/1/2005 u0000004 Smith, Sam u0000005 Jones, Jenny 8/15/2010 u0000006 Little, Larry 8/21/2011 u0000007 Mann, Macho 7/17/2006 u0000008 Pipsqueak, Pippy 4/15/2007 u0000009 Doer, Danny 6/6/2006 u0000010 Jones, Jeff 2/8/2009
Self join Process: pretend there are two copies of the table Use the table name twice Alias at least one of the copies Join the tables (managerID as FOREIGN KEY) Employee (Copy 1: Emp) employeeID name dateOfHire managerID Employee (Copy 2: Mgr) employeeID name dateOfHire managerID M 1
Self join SELECT EMP.employeeID, EMP.name, MGR.name FROM employee as EMP, employee as MGR WHERE EMP.managerID = MGR.employeeID employeeID EMP.name MGR.name u0000002 Overseer, Susie Bossman, Bob u0000003 Worker, William u0000006 Little, Larry u0000007 Mann, Macho u0000010 Jones, Jeff u0000004 Smith, Sam u0000005 Jones, Jenny u0000008 Pipsqueak, Pippy u0000009 Doer, Danny
Multiple relationships Normally there is ONE relationship between two tables (that goes both directions) Occasionally there is actually two relationships between the tables Different “roles”
Multiple relationships Suppose you had a database tracking baseball games You have a “Teams” table and a “games” table A team can participate in a game as the “home” team, OR a team can participate in a game as the “away” team (but never both at the same time). These are two separate relationships
Table structure Team (TeamID, TeamName, Mascot) BallGame (GameID, GameDate, Location, HomeTeamID, HomeScore, AwayTeamID, AwayScore) To find the names for teams participating in a game, you need to get one row of data from the Teams table to get the name of the home team, and a different row of data in the teams table to get the name of the away team.
Process Like with did with self join Pretend like the Team table exists twice
Ballgame GameID GameDate Location HomeTeamID HomeScore AwayTeamID AwayScore Team TeamID TeamName Mascot Team TeamID TeamName Mascot
The query Select GameID, GameDate, H.TeamName As HomeTeam, A. TeamName as AwayTeam From BallGame AS G Team AS H Team AS A Where G.HomeTeamID = H.TeamID link the home copy and G. AwayTeamID = A.TeamID; link the away copy
Multiple functions Let’s look at the demog table in the SNDB. It’s structure is Demog (pt_id, name, zip, gender, race). We need to know what’s the highest pt_id in the table. However, every column in this table was created as a TEXT field. So we can’t just sort the table and scan for the last entry – the data will sort alphabetically, so 1001 will show up early in the list, but 999 will show up late in the list.
Multiple functions We can use a data type conversion function to pretend that the pt_id is a number. (Like we did with sorting data). Cint(pt_id) or to_number(pt_id) Access Oracle
Multiple functions Then once we have it as a number, we can find the maximum value using the max() function Those functions can be nested together. Just be careful to do the parentheses correctly. SELECT max(cint(pt_id)) from demog; If I run this, I see that the highest pt_id in my table is 1255 (your copy may differ slightly).
finally READ the description of other DML query types Insert (add row of data) Update (change existing row) Delete (get rid of a row of data)