PS。添加第二個答案以涵蓋另一點。不要在任何地方都要有Organisation_ID和Person_ID來保存兩者的詳細信息,請創建一個名爲Party的表格,爲每個組織和個人提供唯一的ID - 然後將其與組織/人員記錄相關聯。現在,您可以簡單地使用任意表格中的任何一個表格,您希望能夠將人員ID和組織標識關聯起來。
這是從OO一個共同的模式(面向對象的)世界稱爲政黨格局或甲方模型(谷歌這些條款,以瞭解更多)。
看一看/下面的示例代碼以獲得的是如何工作的一個更好的主意/任何問題,請給我留言:
/* setup */
if OBJECT_ID('Registrations') is not null drop table Registrations
if OBJECT_ID('PartyContact') is not null drop table PartyContact
if OBJECT_ID('ContactType') is not null drop table ContactType
if OBJECT_ID('Organisation') is not null drop table Organisation
if OBJECT_ID('Person') is not null drop table Person
if OBJECT_ID('Party') is not null drop table Party
go
create table ContactType
(
contactType_id int not null identity(1,1) constraint PK_ContactType primary key clustered
, name nvarchar(16) not null constraint UK_ContactType_Name unique
)
go
set identity_insert ContactType on
insert ContactType (contactType_id, name)
select 1, 'WorkEmail'
union select 2, 'PersonalEmail'
union select 3, 'Mobile/Cell'
set identity_insert ContactType off
go
create table Party
(
party_id bigint not null identity(1,1) constraint PK_Party primary key clustered
, name nvarchar(256) not null --this is duplicating the name on the Person/Organisation tables; normally this denormalisation would be bad practice, but here it assists in making data available in the table from which it will be referenced
--any other attributes which you want to be common to all parties
)
go
set identity_insert Party on
insert Party (party_id, name)
select 12, 'Rob Ottow'
union select 13, 'Ann Droid'
union select 14, 'Si Bermann'
union select 112, 'Global Mega Org'
union select 113, 'GeoTech Solutions'
union select 114, 'Think Ink inc.'
set identity_insert Party off
go
create table Person
(
person_id bigint not null identity(1,1) constraint PK_Person primary key clustered
, name nvarchar(256) not null
, party_id bigint not null constraint FK_Person_PartyId references Party(party_id)
constraint UK_Person_PartyId unique
, dob date
)
go
set identity_insert Person on
insert Person (person_id, name, party_id, dob)
select 2, 'Rob Ottow' , 12, '1984-12-25'
union select 3, 'Ann Droid' , 13, null --it's impolite to give a woman's age
union select 4, 'Si Bermann', 14, '1973-06-12'
set identity_insert Person off
go
create table Organisation --en-gb spelling since that's where I'm from
(
organisation_id bigint not null identity(1,1) constraint PK_Organisation primary key clustered
, name nvarchar(256) not null
, party_id bigint not null constraint FK_Organisation_PartyId references Party(party_id)
, taxNumber nchar(12) not null
)
go
set identity_insert Organisation on
insert Organisation (organisation_id, name, party_id, taxNumber)
select 1, 'Global Mega Org' , 112, '123456789012'
union select 2, 'GeoTech Solutions' , 113, ''
union select 3, 'Think Ink inc.' , 114, '9'
set identity_insert Organisation off
go
create table PartyContact
(
partyContact_id bigint not null identity(1,1) constraint PK_PartyContract primary key clustered
, party_id bigint not null constraint FK_PartyContract_PartyId foreign key references Party(party_id)
, contactDetails nvarchar(256) not null
, contactType_id int not null constraint FK_PartyContract_ContactTypeId foreign key references ContactType(contactType_id)
)
go
set identity_insert PartyContact on
insert PartyContact (partyContact_id, party_id, contactDetails, contactType_id)
select 1 ,112 ,'[email protected]' ,1
union select 2 ,12 ,'[email protected]' ,1
union select 3 ,13 ,'[email protected]' ,1
union select 4 ,14 ,'[email protected]' ,1
union select 5 ,113 ,'[email protected]' ,1
union select 6 ,14 ,'[email protected]' ,2
union select 7 ,114 ,'[email protected]' ,2
union select 8 ,13 ,'[email protected]' ,1
union select 9 ,13 ,'' ,3
set identity_insert PartyContact off
go
create table Registrations
(
registration_id bigint not null identity(1,1) constraint PK_Registrations primary key clustered
, party_id bigint not null constraint FK_Registrations_PartyId references Party(party_id)
, name nvarchar(32) not null
, registration_Date date not null
)
go
set identity_insert Registrations on
insert Registrations (registration_id, party_id, name, registration_Date)
select 1 ,112 ,'ORG12' ,'10/05/2013'
union select 2 ,12 ,'P12' ,'10/05/2013'
union select 3 ,13 ,'P13' ,'10/05/2013'
union select 4 ,14 ,'P14' ,'10/05/2013'
union select 5 ,113 ,'O13' ,'10/05/2013'
union select 6 ,114 ,'O14' ,'10/05/2013'
set identity_insert Registrations off
go
/* get the results */
SELECT r.registration_id, r.party_id, p.person_id, o.organisation_id, r.name, c.contactDetails
FROM Registrations r
left outer join Person p on p.party_id = r.party_id
left outer join Organisation o on o.party_id = r.party_id
left outer join
(
select party_id, contactDetails
from PartyContact a
inner join
(
select MIN(partyContact_id) partyContact_id
from PartyContact
where contactType_id in (select contactType_id from ContactType where name = 'WorkEmail')
group by party_id
) b
on a.partyContact_id = b.partyContact_id
) c
ON r.party_id = c.party_id
感謝response.Should最後一行寫着:或x.usage <>'PersonalEmail'?此外,我們的數據庫是在SQL Server 2000上,row_number不是一個可識別的功能,有沒有其他選擇? – Babs 2013-05-14 04:11:19
不等於工作電子郵件在那裏,因爲我原來雖然你想要所有的個人電子郵件,並且只是每個工作郵件的第一個 - 現在修改爲只返回每個工作郵件的第一個。可悲的是我無法仿效SQL2000 /不確切地知道支持什麼,但希望我的修改後的答案能爲此工作;讓我知道。 。 。 – JohnLBevan 2013-05-14 22:17:29
需要我說最後一個查詢就像一個魅力:-)非常感謝! – Babs 2013-05-15 09:04:20