Re: Many-to-Many relationship Query
- From: Vincent Johns <vjohns@xxxxxxxxxxxxxxxxxx>
- Date: Mon, 23 Jan 2006 19:23:21 GMT
Glenn,
I think this will do what you want.
First, my example Tables look like these. In the first one, the key value is a text string and not a number. (This distinction will be important later, in the function that matches its value with another Table.)
[Customer] Table Data*** View:
Customer_ID Customer ----------- ---------------- 001 Joe Bloggs Ltd 007 Bond, James 123 Acme Explosives
In the following Table, the primary key, [Employee_ID], is an Autonumber field.
[Employee] Table Data*** View:
Employee_ID Employee ----------- -------- -1911156243 Jim -1516216861 Sarah -560162532 Glenn 1748767914 Harry
I usually apply Lookup properties to all foreign keys, but please remember that even though they look different using Lookups, the values actually stored in the Tables are the key values.
[Cust-Empl] Table Data*** View (without Lookup properties): Customer_ID Employee_ID ----------- ----------- 001 -1911156243 001 -1516216861 123 -1516216861 001 -560162532 001 1748767914 123 1748767914
This is not very pretty, so after applying Lookup properties to the two foreign keys, the table looks like this:
[Cust-Empl] Table Data*** View:
Customer_ID Employee_ID -------------- ----------- Joe Bloggs Ltd Jim Joe Bloggs Ltd Sarah Acme Explosives Sarah Joe Bloggs Ltd Glenn Joe Bloggs Ltd Harry Acme Explosives Harry
The Query that I think you have already defined in your database looks something like this.
[Q01_EmployeesByCustomer] SQL:
SELECT Customer.Customer_ID, Customer.Customer, Employee.Employee FROM Employee INNER JOIN (Customer INNER JOIN [Cust-Empl] ON Customer.Customer_ID = [Cust-Empl].Customer_ID) ON Employee.Employee_ID = [Cust-Empl].Employee_ID ORDER BY Customer.Customer, Employee.Employee;
.... and it produces a list with repeating customer names.
[Q01_EmployeesByCustomer] Query Data*** View:
Customer_ID Customer Employee ----------- ---------------- -------- 123 Acme Explosives Harry 123 Acme Explosives Sarah 001 Joe Bloggs Ltd Glenn 001 Joe Bloggs Ltd Harry 001 Joe Bloggs Ltd Jim 001 Joe Bloggs Ltd Sarah
The following function reads this Query and produces a list of employee names similar to what you asked for. Instead of having it call the named Query, [Q01_EmployeesByCustomer], as it does, you might choose to put the entire SQL of [Q01_EmployeesByCustomer] into this code. However, depending on how you prefer to maintain your database, doing it as I suggest here allows you to maintain the Query in Query Design View, and the only SQL you have to look at is the filter, and the filter is pretty short.
'List all employees for the specified customer
Public Function EmpByCust( _
CustomerID As String) As String 'Unfiltered Query
Dim rsEmployeesByCustomer As DAO.Recordset 'Filtered to return only those matching the argument
Dim rsFiltered As DAO.Recordset 'Name of unfiltered Query
Const strQ01 As String = "Q01_EmployeesByCustomer" 'Value to be returned, such as
' "Glenn; Harry; Jim; Sarah"
Dim strResult As String
Set rsEmployeesByCustomer = _ CurrentDb.OpenRecordset( _ strQ01, dbOpenSnapshot)
With rsEmployeesByCustomer
.Filter = "Customer_ID = '" _
& CustomerID & "'"
.MoveLastSet rsFiltered = .OpenRecordset(dbOpenSnapshot)
End With 'rsEmployeesByCustomer
With rsFiltered
If .BOF Then
EmpByCust = "<Nobody>"
Exit Function
End If '.BOF ... strResult = .Fields("Employee")
.MoveNext While Not .EOF
strResult = strResult & "; " _
& .Fields("Employee")
.MoveNext
Wend 'Not .EOF ...End With 'rsEmployees
EmpByCust = strResult
End Function 'EmpByCust()
And the following Query invokes this function to produce the list you wanted.
[Q02_EmployeeLists] SQL:
SELECT Customer.Customer_ID, Customer.Customer, EmpByCust([Customer]![Customer_ID]) AS Employees FROM Customer ORDER BY Customer.Customer_ID;
[Q02_EmployeeLists] Query Data*** View:
Customer_ID Customer Employees ----------- ---------------- ------------------------ 001 Joe Bloggs Ltd Glenn; Harry; Jim; Sarah 007 Bond, James <Nobody> 123 Acme Explosives Harry; Sarah
-- Vincent Johns <vjohns@xxxxxxxxxxxxxxxxxx> Please feel free to quote anything I say here.
Glenn Brown wrote:
Thanks for your reply. I should have explained myself a little better. I've already done what you suggested. That part is working fine.[...]
I want a query showing all the Customers with one calculated field that shows all the related Employee's. So Joe Bloggs Ltd (say customer 1) will have a calculated field called Employees with say "Glenn; Jim; Harry; Sarah" in it. These are obviously four separate Employees that are linked to this customer. Some code needs to be written to get this I think? The code bit is what I need.
I know I can create a inner join between the two tables to get a list of related Employee's. The problem with this is - if the Customer is linked to two Employee's, the Customer will be listed twice in the Query. This isn't want I want.
Regards, Glenn
"Vincent Johns" wrote:
Glenn Brown wrote:
I've got a database with a many-to-many relationship between two tables (Employees and Customers). By this I mean I have a table that sits in-between both tables and records the relationship. I want to create a query which lists all the Customers with a calculated field that lists all the Employees within it.
For example Customer ID Customer Employee’s 001 Joe Bloggs Ltd Glenn; Jim; Harry; Sarah
Does anyone have any ideas? Any help would be appreciated.
Regards, Glenn Brown
.
- References:
- Re: Many-to-Many relationship Query
- From: Vincent Johns
- Re: Many-to-Many relationship Query
- From: Glenn Brown
- Re: Many-to-Many relationship Query
- Prev by Date: Re: Like operator with accented character
- Next by Date: Re: Crosstab query problem.
- Previous by thread: Re: Many-to-Many relationship Query
- Next by thread: Re: Many-to-Many relationship Query
- Index(es):