I'm learning SQL and Microsoft Access at the same time. I have a
database dump that I'm importing into Access & analyzing, and need to
do a certain type of query. I'll simplify the database structure for
this question.
Employee
--------
ID
Name
Team
-----------
ID
ManagerA (employee.id)
ManagerB (employee.id)
TeamMembers
-----------
TeamID
EmployeeID
I'd like, first, a simple list of teams as follows:
TeamID, ManagerA name, ManagerB name
Then I want a simple list of team members as follows:
Employee Name, TeamID, ManagerA, ManagerB
Caveat 1:
The "Employee.ID" field contains a large number of zero values, which
contain data for contractors. No employee ID, but they have other
useful employee data in the system, and ways of referencing their
data.
Caveat 2:
The Teams table contains some teams with no Manager A, some with no
Manager B, and some with neither. A missing value is indicated with a
zero.
Caveat 3:
I did not model this data, and have no control over its structure. It
is actually from a large database from a large church, and I'm simply
getting a set of flat-file exports to work from for my analysis work.
The data is structured the way it is for, one hopes, good reasons. I
was a bit surprised myself to see multiple zero values in the
supposedly key field, but they have a big database system built around
this structure that seems to work.
Problem:
I want exactly one row for each Team for the first report.
If I do a basic join, I end up with more than one row for each row in
the Teams table. The zero values in the Teams table end up matching
several rows in the Employee table, and vice versa.
What I need, I think (as a rank amateur), is a query to eliminate
zero-values from employees, then a set of two left join operations:
one to left join the Team.ManagerA to the filtered employees table,
then a second to left join Team.ManagerB to the filtered employees
table.
The reason for the query ('where Employee.ID > 0') is to eliminate the
multiple zero values in the ID field.
The reason for the LEFT JOINs is to preserve the unmatched rows in the
Team table.
That way, I'd be guaranteed exactly one and only one result row for
each row in the Teams table. I'll get a row even if the team has no
managers, which is good.
The problem is, I can't figure out the proper SQL syntax. That is:
1) query employees for >0 value in ID
2) look up Team.ManagerA name in 1) above
3) look up Team.ManagerB name in 1) above
The syntax I attempted was:
SELECT T.*, E1.name as "Manager A", E2.name as "Manager B"
FROM Team T LEFT JOIN (select * from Employee E1 where E1.ID > 0) ON
(T.ManagerA = E1.ID)
LEFT JOIN (select * from Employee E2 where E2.ID >0) ON (T.ManagerB =
E2.ID)
When I try this, I get a non-helpful syntax error. I know there must
be a way of expressing this kind of query in SQL.
So, perhaps my question is best phrased as:
1) What is wrong with my query syntax above?
2) In general, how can I use the results of a query as a "table" in
yet another query? Do I have to do it with two separate queries where
the first query creates a "phantom" table (or whatever its called in
SQL)? Or is there a way to do it within a single extended SQL
statement?
3) In general, how do I do "parallel left joins" (my terminology)? How
can I left join Table2.A to Table1.ID and join Table2.B to Table1.ID
to end up with one lovely table containing all rows from Table2 with
"lookup values" from Table1?
Thank you,
--Vaughn |