You'll probably want to allow for the same contact being a client of more
than one of your clients. What this entails is a many-to-many relationship
between the individuals involved. Normally a many to-many relationship is
modelled between two tables by a third table, e.g.
Orders---<ProductsOrdered>----Products
In this relationship each order might be for many products and each product
might be included in many orders. The ProductsOrdered table models this by
having two foreign key columns OrderID and ProductID which reference the
primary keys of the Orders and Products table. The ProductsOrdered table
would also be likely to have other columns such as Quantity and UnitPrice,
which are attributes of the relationship type which the table models.
In your case however, if you have a single table of all people whether they
are your clients or clients of your clients, then the many-to-many
relationship is between two instances of the same table like so:
People---<ClientList>----People
The ClientList table in this case again has two foreign key columns,
ClientOfID and ClientID say, but in this case they both reference the primary
key of the single table People (you can of course give these tables and
columns whatever names you wish). So if someone with a PersonID value of 42
has clients with PersonID values of 99 and 123 the ClientList table would
have the following rows:
ClientOfID ClientID
42 99
42 123
If PersonID 99 is also a client of someone else, PersonID 66, then there
would also be a row:
ClientOfID ClientID
66 99
But PersonID 99 might also have their own clients, say 135 and 177, so
there would be rows:
ClientOfID ClientID
99 135
99 177
If you are only interested in the first level of clientship for each person
there is no problem; you simply join two instances of the people table to the
ClientList table:
SELECT P1.Person, P2.Person AS Contact
FROM People AS P1, People AS P2, ClientList
WHERE P1.PersonID = ClientList.ClientOfID
AND P2.PersonID = ClientList.ClientID;
If you want to drill down through the levels of clientship, however, and
show the 'chain' of clients, sub-clients, sub-sub-clients etc for each
person, it gets trickier as this involves recursion, and queries cannot be
recursive. This is analogous to the classic database problem of a 'bill of
materials' or 'parts explosion'. To achieve recursion through a variable
number of levels is not trivial, but it is possible to achieve the same
result fairly simply for a fixed number of levels by a series of outer joins
in a query. Here's an example using tables Parts and PartStructure which
does this for 9 levels:
SELECT P1.PartName AS Part,
[P2].[PartName]+(" (" & [PS1].[Quantity] & ")") AS Component1,
[P3].[PartName]+(" (" & [PS2].[Quantity] & ")") AS Component2,
[P4].[PartName]+(" (" & [PS3].[Quantity] & ")") AS Component3,
[P5].[PartName]+(" (" & [PS4].[Quantity] & ")") AS Component4,
[P6].[PartName]+(" (" & [PS5].[Quantity] & ")") AS Component5,
[P7].[PartName]+(" (" & [PS6].[Quantity] & ")") AS Component6,
[P8].[PartName]+(" (" & [PS7].[Quantity] & ")") AS Component7,
[P9].[PartName]+(" (" & [PS8].[Quantity] & ")") AS Component8,
[P10].[PartName]+(" (" & [PS9].[Quantity] & ")") AS Component9
FROM Parts AS P1
LEFT JOIN (((((((((((((((((PartStructure AS PS1
LEFT JOIN PartStructure AS PS2 ON PS1.MinorPartNum = PS2.MajorPartNum)
LEFT JOIN PartStructure AS PS3 ON PS2.MinorPartNum = PS3.MajorPartNum)
LEFT JOIN PartStructure AS PS4 ON PS3.MinorPartNum = PS4.MajorPartNum)
LEFT JOIN PartStructure AS PS5 ON PS4.MinorPartNum = PS5.MajorPartNum)
LEFT JOIN PartStructure AS PS6 ON PS5.MinorPartNum = PS6.MajorPartNum)
LEFT JOIN PartStructure AS PS7 ON PS6.MinorPartNum = PS7.MajorPartNum)
LEFT JOIN PartStructure AS PS8 ON PS7.MinorPartNum = PS8.MajorPartNum)
LEFT JOIN PartStructure AS PS9 ON PS8.MinorPartNum = PS9.MajorPartNum)
LEFT JOIN Parts AS P2 ON PS1.MinorPartNum = P2.PartNum)
LEFT JOIN Parts AS P3 ON PS2.MinorPartNum = P3.PartNum)
LEFT JOIN Parts AS P4 ON PS3.MinorPartNum = P4.PartNum)
LEFT JOIN Parts AS P5 ON PS4.MinorPartNum = P5.PartNum)
LEFT JOIN Parts AS P6 ON PS5.MinorPartNum = P6.PartNum)
LEFT JOIN Parts AS P7 ON PS6.MinorPartNum = P7.PartNum)
LEFT JOIN Parts AS P8 ON PS7.MinorPartNum = P8.PartNum)
LEFT JOIN Parts AS P9 ON PS8.MinorPartNum = P9.PartNum)
LEFT JOIN Parts AS P10 ON PS9.MinorPartNum = P10.PartNum)
ON P1.PartNum = PS1.MajorPartNum;
This query was actually written s the RecordSource for a report which shows
the structure of a components in a tree-like format. It was produced, along
with an example of how to produce a parts explosion over a variable number of
levels, for a magazine article some years ago. The file won't be available
on their web site now, but if you are interested I can send you a copy if you
mail me at ken<dot>sheridan<at>dsl<dot>pipex<dot>com.
Ken Sheridan
Stafford, England
Rachelle said:
I am creating a client database for my business. Each of my clients has
their own database of clients. I need to keep their database of clients for
each of them. Is it possible to creat a contact within a contact