简体   繁体   中英

ms-access phone table design for multiple individuals with multiple addresses

How do I design tables and relationships for multiple contact information, for several individuals?

The contact information is related to each other, especially addresses and phone numbers.

The goal is to make a structure which works for as many scenarios as possible. clients, users, students, supervisors and employees or other categories used with labels.

The contact information one wants to, or has to, keep track of in the database for the company or organisation can differ quite a lot, depending on what they work with.

This is something I have a hard time tackling, and the way to solve this is very divided over the net.

Other sources at the bottom.


  • Each client /employee /student can have one or more addresses, like privet and work addresses.
  • Each client /employee /student can have one or more phone numbers, like mobile, work, private (and fax)
    1. An employee and have one or more pages as well.
  • Each client /employee /student can have more then one email addresses, like private and work.

My current table design. (Related tables)

tblClients:

  • ClientID (PK)(Indexed no duplicates)
  • KlientKey (security number or personal ID)(Indexed no duplicates)
  • FirstName
  • LastName

tblAddress:

  • AddressID (PK)(Indexed no duplicates)
  • ClientID (FK)(indexed with duplicates)
  • CategoryID (FK)(ID = 1 or 4)
  • Address
  • City
  • ZIP

tblNumber:

  • NumberID (PK)(Indexed no duplicates)
  • ClientID (FK)(indexed with duplicates)
  • AddressID (FK)(indexed with duplicates)(No Table relations, experimental.)
  • Category(FK)(ID = 2 or 3 or 5)
  • Number

tblEmail:

  • EmailID (PK)(Indexed no duplicates)
  • ClientID (FK)(Indexed with duplicates)
  • CategoryID (FK)(ID = 1 or 4)
  • Email

tblCategorys:

  • CategoryID (PK)(Indexed no duplicates)
  • Category (1; Private, 2; Phone, 3; Mobile, 4; Work, 5; Fax)

This structure generates duplicates whenever the data is listed in a form, query or report. And the issue is related to phone numbers and addresses. The conflict occurs whenever two addresses or phone numbers with the under the same category has to be displayed in a list. Well, that is what believe.

As you can see below the contact information is duplicated. I want to prevent this from happening. Plus, I want to prevent a phone number to be displayed on a record which doesn't have the displayed phone number. These reports only shows private addresses, to the household(s) with other words, if I make any sense here. (Img is removed duo reputation limit.)

As shown in the picture is how i want the reports look like. I achieve this result with the new tbl design, new queries and a little vba. This is just experimental nothing more. Img 2 - experimental

Clients & Email

SELECT tblClients.ClientID, 
       tblClients.ClientKey, 
       [tblClients].[LastName] & ",  " & [tblClients].[Firstname] AS Klient,            
       tblClients.Startdate, 
       tblClients.EndDate, 
       [qryList(PrivateEmails)].Email, 
       tblClients.LastName
FROM tblClients 
LEFT JOIN [qryList(PrivateEmails)] 
     ON tblClients.ClientID = [qryList(PrivateEmails)].ClientID;

Addresses & Phone numbers

SELECT tblAddress.ClientID,
       tblAddress.Address, 
       tblAddress.ZIP, 
       tblAddress.City, 
       tblNumber.Number, 
       tblAddress.CategoryID, 
       tblNumber.AddressID, 
       tblNumber.CategoryID

FROM tblAddress 
LEFT JOIN tblNumber 
     ON tblAddress.AddressID = tblNumber.AddressID
WHERE (((tblAddress.CategoryID) 
      Is Null Or (tblAddress.CategoryID)=1) 
         AND ((tblNumber.AddressID) 
      Is Null Or (tblNumber.AddressID)>=1) 
         AND ((tblNumber.CategoryID) 
      Is Null Or (tblNumber.CategoryID)=2));

Final query

SELECT Clients.*, [qryAddress&PhoneNuber(Private)].*
FROM Clients 
LEFT JOIN [qryAddress&PhoneNuber(Private)] 
     ON Clients.ClientID = [qryAddress&PhoneNuber(Private)].ClientID;

vba for populate the addressID in tblnumbers, triggerd when the user saves changes in a form when a new record is added or edited.

' A Dynamic array would be usful whenever multiple addresses and phone numbers is added as private.
   If IsNull(varAddressID) = 0 Then
        If Me.frmAddress.Form.txtCategoryID = 1 Then
            If Me.frmNumber.Form.txtCategoryID = 2 Then
                Me.frmNumber.Form.txtAddressID = Me.frmAddress.Form.txtAddressID
            End If
        End If
    End If

This is the sql qry i use when only want to see the private contact information.

SELECT    tblClients.ClientKey,
          [tblClients].[LastName] & ".  " & [tblClients].[FirstName] AS Klient,
          tblClients.Startdate,
          tblClients.EndDate,
          [qryList(NumberPrivate)].Number,
          [qryList(PrivateAddresses)].Address,
          [qryList(PrivateAddresses)].ZIP,
          [qryList(PrivateAddresses)].City, 
          [qryList(PrivateEmails)].Email 
FROM ((
LEFT JOIN [qryList(PrivateEmails)] 
       ON tblClients.ClientID = [qryList(PrivateEmails)].
LEFT JOIN [qryList(PrivateAddresses)] 
       ON tblClients.ClientID = [qryList(PrivateAddresses)].
LEFT JOIN [qryList(NumberPrivate)] 
       ON tblClients.ClientID = [qryList(NumberPrivate)].ClientID 
WHERE  ((([qryList(NumberPrivate)].CategoryID) Is Null 
                 Or ([qryList(NumberPrivate)].CategoryID)=2) 
    AND (([qryList(PrivateAddresses)].CategoryID) Is Null 
                 Or ([qryList(PrivateAddresses)].CategoryID)=1) 
    AND (([qryList(PrivateEmails)].CategoryID) Is Null
                 Or ([qryList(PrivateEmails)].CategoryID)=1))
ORDER BY  tblClients.ClientKey DESC, 
          [tblClients].[LastName] & ".  " & [tblClients].[FirstName] DESC,
          tblClients.Startdate,
          tblClients.EndDate DESC; 

Other sources with the same or similar topic:

http://www.sqlservercentral.com/Forums/Topic637723-361-1.aspx

Normalize or Denormalize: Store Contact Details (Phone Numbers) in separate Table? Search Performance?

Your data model is good based on the data you want to store.

The question is more about the output -- how can I query the data so it doesn't show duplicate rows when I don't want to.

For this question there are many answers depending on what you are trying to do. (ie Group Values on a Report (usual solution), Concatenate emails into a single row, Grab the max or min value of the sub objects, etc.)

I would recommend post another question with your query and any problems that you are seeing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM