0

以下のように 2 つのテーブルがあり、両方のテーブルに person_id または organization_id が入力されているシナリオがあります。

表1

email_id, person_id, organisation_id, email_address   Usage  
1         NULL       12               O12@EMAIL.COM   WorkEmail  
2         12         NULL             P12@EMAIL.COM   WorkEmail  
3         13         NULL             P13@EMAIL.COM   WorkEmail  
4         14         NULL             P14@EMAIL.COM   WorkEmail  
5         NULL       13               O13@EMAIL.COM   WorkEmail  
6         14         NULL             P14_p@EMAIL.COM PersonalEmail  
7         NULL       14               O14@EMAIL.COM   PersonalEmail  
8         13         NULL             P13_2@EMAIL.COM WorkEmail 

テーブル_2

registration_id, person_id, organisation_id, name, registration_Date  
1                NULL       12                ORG12 10/05/2013   
2                12         NULL              P12   10/05/2013  
3                13         NULL              P13   10/05/2013  
4                14         NULL              P14   10/05/2013  
5                NULL       13                O13   10/05/2013  
6                NULL       14                O14   10/05/2013  

各登録レコードの workemail を提供する select ステートメントが必要です。登録レコードに複数の勤務先メール アドレスがある場合、最初のレコードを選択する必要があります (例: 表 1 の email_id 3 と 8 のレコード):

registration_id, person_id, organisation_id, name, email address  
1                NULL       12           ORG12 O12@EMAIL.COM   
2                12         NULL         P12   P12@EMAIL.COM  
3                13         NULL         P13   P13@EMAIL.COM  
4                14         NULL         P14   P14@EMAIL.COM  
5                NULL       13           O13   O13@EMAIL.COM  
6                NULL       14           O14   NULL  

私は次のことを試みましたが、これが最も効率的な方法であるかどうかはわかりません。その上、それは私が必要とするものをまったく与えてくれません:

SELECT t1.registration_id, t1.person_id, t1.organisation_id, t1.name, t2.email_Address
FROM table2 t1
LEFT JOIN table1 ON t2.person_id = t1.person_id
    OR
    t2.organisation_id = t1.organisation_id
4

2 に答える 2

1

修正された回答

/* setup */
create table Table_1
(
      email_id bigint not null --identity(1,1)
    , person_id bigint 
    , organisation_id bigint
    , email_address nvarchar(256) not null
    , Usage nvarchar(16) not null
)
insert Table_1 (email_id, person_id, organisation_id, email_address,   Usage)
      select 1         ,NULL       ,12               ,'O12@EMAIL.COM'   ,'WorkEmail'  
union select 2         ,12         ,NULL             ,'P12@EMAIL.COM'   ,'WorkEmail'  
union select 3         ,13         ,NULL             ,'P13@EMAIL.COM'   ,'WorkEmail'  
union select 4         ,14         ,NULL             ,'P14@EMAIL.COM'   ,'WorkEmail'  
union select 5         ,NULL       ,13               ,'O13@EMAIL.COM'   ,'WorkEmail'  
union select 6         ,14         ,NULL             ,'P14_p@EMAIL.COM' ,'PersonalEmail'  
union select 7         ,NULL       ,14               ,'O14@EMAIL.COM'   ,'PersonalEmail'  
union select 8         ,13         ,NULL             ,'P13_2@EMAIL.COM' ,'WorkEmail' 

create table Table_2
(
      registration_id bigint not null --identity(1,1)
    , person_id bigint
    , organisation_id bigint
    , name nvarchar(32) not null
    , registration_Date date not null
)
insert Table_2 (registration_id, person_id, organisation_id, name, registration_Date)
      select 1                ,NULL       ,12                ,'ORG12' ,'10/05/2013'   
union select 2                ,12         ,NULL              ,'P12'   ,'10/05/2013' 
union select 3                ,13         ,NULL              ,'P13'   ,'10/05/2013'
union select 4                ,14         ,NULL              ,'P14'   ,'10/05/2013'
union select 5                ,NULL       ,13                ,'O13'   ,'10/05/2013'
union select 6                ,NULL       ,14                ,'O14'   ,'10/05/2013'


/* get the results */
SELECT t2.registration_id, t2.person_id, t2.organisation_id, t2.name, t1.email_Address
FROM table_2 t2
left outer join 
(
    select person_id, organisation_id, email_address
    from Table_1 a
    inner join 
    (
        select MIN(email_id) email_id
        from Table_1 
        where Usage = 'WorkEmail'       
        group by person_id, organisation_id
    ) b
    on a.email_id = b.email_id      
) t1 
    ON t2.person_id = t1.person_id
    OR t2.organisation_id = t1.organisation_id

元の回答

これがあなたが求めているものだと思います:

select x.registration_id, x.person_id, x.organisation_id, x.name, x.email_Address
from
(
    SELECT t2.registration_id, t2.person_id, t2.organisation_id, t2.name, t1.email_Address, t1.usage
    , row_number() over (partition by t2.registration_id, t1.usage order by t1.email_id) r
    FROM table_2 t2
    LEFT JOIN table_1 t1 
        ON t2.person_id = t1.person_id
        OR t2.organisation_id = t1.organisation_id
) x
where (x.r = 1 and x.usage = 'WorkEmail') --limit to the first email address if there are multiple work email matches for the same registration (table2) record
or x.usage <> 'WorkEmail' --if it's not work email, don't limit the number
于 2013-05-13T23:17:22.560 に答える
0

ps。別のポイントをカバーするために2番目の回答を追加します。両方の詳細を保持したいすべての場所に Organization_ID と Person_ID を配置するのではなく、各組織と個人に一意の ID を提供する Party というテーブルを作成し、それを Organization/Person レコードに関連付けます。これで、個人 ID と組織 ID を関連付けたい任意のテーブルに 1 つの列を使用するだけで済みます。

これは、パーティ パターンまたはパーティ モデルとして知られる OO (オブジェクト指向) の世界の一般的なパターンです (詳細については、これらの用語を Google で検索してください)。

これがどのように機能するかをよりよく理解するために、以下のサンプルコードを見て/遊んでください/質問があれば、私に声をかけてください:

/* 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, '012345678901'
union select 3, 'Think Ink inc.'    , 114, '901234567890'
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        ,'O12@EMAIL.COM'   ,1
union select 2         ,12         ,'P12@EMAIL.COM'   ,1
union select 3         ,13         ,'P13@EMAIL.COM'   ,1
union select 4         ,14         ,'P14@EMAIL.COM'   ,1
union select 5         ,113        ,'O13@EMAIL.COM'   ,1
union select 6         ,14         ,'P14_p@EMAIL.COM' ,2
union select 7         ,114        ,'O14@EMAIL.COM'   ,2
union select 8         ,13         ,'P13_2@EMAIL.COM' ,1
union select 9         ,13         ,'01234 567890'    ,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
于 2013-05-16T08:38:01.660 に答える