View Tables with multiple foreign keys from a single table.

Posted on 2009-02-19
Last Modified: 2012-06-27
How to create a "ContactInformation" view table in order to see all data fields from the associated foreign key table, mainly in question 3 phone numbers FK_HomePhoneID, FK_WorkPhoneID, and FK_MobilePhoneID, these foreign keys are associated with the phone table PK_PhoneID.

See attachment for details
Note: Design partly taken from larger system.
create table Account (AccountID uniqueidentifier default newsequentialid() not null, AccountNumber varchar(128) null unique, UserID varchar(128) not null, Password nvarchar(128) not null, RegistrationDate datetime default getdate() not null, constraint PK_Account primary key (AccountID));

create table PhoneType (PhoneTypeID uniqueidentifier default newsequentialid() not null, PhoneTypeCode int not null unique, Name nvarchar(50) not null, constraint PK_PhoneType primary key (PhoneTypeID));

create table Phone (PhoneID uniqueidentifier default newsequentialid() not null, Number nvarchar(50) not null, Ext nvarchar(10) null, isPrimary bit default 0 not null, PhoneTypeID uniqueidentifier not null, constraint PK_Phone primary key (PhoneID));

create table AccountContactInformation (AccountContactInformationID uniqueidentifier default newsequentialid() not null, ProfileID uniqueidentifier not null unique, ContactInformationID uniqueidentifier not null unique, constraint PK_AccountContactInformation primary key (AccountContactInformationID));

create table CountryOfCitizenship (CountryOfCitizenshipCode varchar(2) not null, Name nvarchar(100) not null unique, constraint PK_CountryOfCitizenship primary key (CountryOfCitizenshipCode));

create table ContactInformation (ContactInformationID uniqueidentifier default newsequentialid() not null, FirstName nvarchar(100) not null, LastName nvarchar(100) not null, AddressID uniqueidentifier not null, CountryOfCitizenshipCode varchar(2) not null, AccountCurrencyID uniqueidentifier not null, HomePhoneID uniqueidentifier null, WorkPhoneID uniqueidentifier null, MobilePhoneID uniqueidentifier null, constraint PK_ContactInformation primary key (ContactInformationID));

create table Profile (ProfileID uniqueidentifier default newsequentialid() not null, AccountID uniqueidentifier not null unique, constraint PK_Profile primary key (ProfileID));

create table AccountPhone (AccountPhoneID uniqueidentifier default newsequentialid() not null, ProfileID uniqueidentifier not null, PhoneID uniqueidentifier not null unique, constraint PK_AccountPhone primary key (AccountPhoneID));

alter table Phone add constraint FK_Phone_PhoneTypeID_PhoneType foreign key (PhoneTypeID) references PhoneType (PhoneTypeID);

alter table ContactInformation add constraint FK_ContactInformation_HomePhoneID_Phone foreign key (HomePhoneID) references Phone (PhoneID);

alter table ContactInformation add constraint FK_ContactInformation_WorkPhoneID_Phone foreign key (WorkPhoneID) references Phone (PhoneID);

alter table ContactInformation add constraint FK_ContactInformation_MobilePhoneID_Phone foreign key (MobilePhoneID) references Phone (PhoneID);

alter table AccountContactInformation add constraint FK_AccountContactInformation_ContactInformationID_ContactInformation foreign key (ContactInformationID) references ContactInformation (ContactInformationID);

alter table ContactInformation add constraint FK_ContactInformation_CountryOfCitizenshipCode_CountryOfCitizenship foreign key (CountryOfCitizenshipCode) references CountryOfCitizenship (CountryOfCitizenshipCode);

alter table Profile add constraint FK_Profile_AccountID_Account foreign key (AccountID) references Account (AccountID);

alter table AccountContactInformation add constraint FK_AccountContactInformation_ProfileID_Profile foreign key (ProfileID) references Profile (ProfileID);

alter table AccountPhone add constraint FK_AccountPhone_PhoneID_Phone foreign key (PhoneID) references Phone (PhoneID);

alter table AccountPhone add constraint FK_AccountPhone_ProfileID_Profile foreign key (ProfileID) references Profile (ProfileID);

Open in new window

Question by:_AstroBoy
    LVL 22

    Expert Comment

    Something like this:

    SELECT C.ContactInformationID, H.Number HomeNumber, W.Number WorkNumber, M.Number MobileNumber
    FROM ContactInformation C
    LEFT JOIN Phone H
    ON C.HomePhoneID = H.PhoneID
    LEFT JOIN Phone W
    ON C.WorkPhoneID = W.PhoneID
    LEFT JOIN Phone M
    ON C.MobilePhoneID = M.PhoneID ;

    My preference would be to redesign something more like the following. This makes it easier to retrieve all the numbers for a contact (one join instead of three), you aren't limited to three numbers and it doesn't require you to duplicate a number if the number is more than one category of: Home/Work/Mobile.

    CREATE TABLE dbo.ContactPhone
      REFERENCES ContactInformation (ContactInformationID),
      REFERENCES Phone (PhoneID),
      IsHome BIT NOT NULL,
      IsWork BIT NOT NULL,
      IsMobile BIT NOT NULL,
      PRIMARY KEY (ContactInformationID, PhoneID));
    LVL 51

    Accepted Solution

    Here you go...  That diagram is quite involved... Can only see one use really for Phone Type and that is for Account Phone. Which I also have read as being mandatory (ie inner join).

    The Home, Work, and Mobile could also have extension etc and an indicator as to preferred / primary phone - can do more on that if you want...

    I think all the data relationships are there matching your diagram - not every column, but that is easy to add in.

    SELECT      dbo.Account.AccountID, dbo.Profile.ProfileID,
                dbo.ContactInformation.HomePhoneID, isnull(HP.Number,'') as HomePhoneNo,
                dbo.ContactInformation.WorkPhoneID, isnull(WP.Number,'') as WorkPhoneNo,
                dbo.ContactInformation.MobilePhoneID, isnull(MP.Number,'') as MobilePhoneNo,
                dbo.AccountPhone.PhoneID, isnull(AP.Number,'') as AccountPhoneNo,
                dbo.PhoneType.Name as AccountPhoneType
    FROM        dbo.ContactInformation 
    INNER JOIN  dbo.AccountContactInformation ON dbo.ContactInformation.ContactInformationID = dbo.AccountContactInformation.ContactInformationID 
    INNER JOIN  dbo.CountryOfCitizenship ON dbo.ContactInformation.CountryOfCitizenshipCode = dbo.CountryOfCitizenship.CountryOfCitizenshipCode 
    INNER JOIN  dbo.Profile ON dbo.AccountContactInformation.ProfileID = dbo.Profile.ProfileID 
    INNER JOIN  dbo.Account ON dbo.Profile.AccountID = dbo.Account.AccountID
    INNER JOIN  dbo.AccountPhone on dbo.Profile.ProfileID = dbo.AccountPhone.ProfileID    -- if account phone, why profile id ?
    INNER JOIN  dbo.Phone AP ON dbo.AccountPhone.PhoneID = AP.PhoneID 
    INNER JOIN  dbo.PhoneType ON dbo.Phone.PhoneTypeID = dbo.PhoneType.PhoneTypeID        -- PhoneType does seem superfluous for the rest
    LEFT JOIN   dbo.Phone HP ON dbo.ContactInformation.HomePhoneID = HP.PhoneID 
    LEFT JOIN   dbo.Phone WP ON dbo.ContactInformation.WorkPhoneID = WP.PhoneID 
    LEFT JOIN   dbo.Phone MP ON dbo.ContactInformation.MobilePhoneID = MP.PhoneID 

    Open in new window


    Featured Post

    How to improve team productivity

    Quip adds documents, spreadsheets, and tasklists to your Slack experience
    - Elevate ideas to Quip docs
    - Share Quip docs in Slack
    - Get notified of changes to your docs
    - Available on iOS/Android/Desktop/Web
    - Online/Offline

    Join & Write a Comment

    After restoring a Microsoft SQL Server database (.bak) from backup or attaching .mdf file, you may run into "Error '15023' User or role already exists in the current database" when you use the "User Mapping" SQL Management Studio functionality to al…
    If you have heard of RFC822 date formats, they can be quite a challenge in SQL Server. RFC822 is an Internet standard format for email message headers, including all dates within those headers. The RFC822 protocols are available in detail at:   ht…
    Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…
    Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

    729 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    24 Experts available now in Live!

    Get 1:1 Help Now