2013-11-09 173 views
2

我有兩個歸SQL Server 2008的表,一個名字,另一個用於郵件:非規範化SQL Server表

create table Name (NameId int, Name varchar(50)) 
create table Email (NameId int, Email varchar(50)) 
go 

insert into Name values (1, 'JOHN SMITH') 
insert into Name values (2, 'MARY SMITH') 
insert into Name values (3, 'PHILL TAYLOR') 
go 

insert into Email values (1, '[email protected]') 
insert into Email values (1, '[email protected]') 
insert into Email values (1, '[email protected]') 
insert into Email values (2, '[email protected]') 
insert into Email values (3, '[email protected]') 
insert into Email values (3, '[email protected]') 
insert into Email values (3, '[email protected]') 
insert into Email values (3, '[email protected]') 
go 

當我加入這些表我有幾行,只有一個電子郵件,其中一行:

Select name, email 
from Name inner join Email on name.NameId=email.NameId 


NAME   EMAIL 
------------- -------------------------- 
JOHN SMITH  [email protected] 
JOHN SMITH  [email protected] 
JOHN SMITH  [email protected] 
MARY SMITH  [email protected] 
PHILL TAYLOR [email protected] 
PHILL TAYLOR [email protected] 
PHILL TAYLOR [email protected] 
PHILL TAYLOR [email protected] 

但我需要有相同的行中的所有電子郵件,以滿足預定義的佈局:

NAME   EMAIL1    EMAIL2   EMAIL3      EMAIL4 
------------- ----------------- --------------- -----------------------  ----------------- 
JOHN SMITH  [email protected] [email protected] [email protected] 
MARY SMITH  [email protected] 
PHILL TAYLOR [email protected] [email protected] [email protected] [email protected] 

是否可以使用單個選擇?

任何想法將是非常讚賞

TIA

裏卡多·諾蓋拉

+0

請問逗號分隔值是否可以完成這項工作?這更簡單.. –

+0

你是否建議如果名稱相同,那麼電子郵件地址是指同一個人?這不符合現實,除非你將它限制在一些(在問題中未標明的)標準。 –

+0

你是什麼意思的預定義佈局?我的意思是你的預定義佈局是什麼?將逗號分隔的電子郵件列表可以正常使用嗎? –

回答

2

它可以在1選擇完成。如果您只需要前4個電子郵件地址並將它們用作特定列。使用電子郵件表上的RowNumber函數爲每個用戶的mailaddresses編號。此示例假定電子郵件地址應按字母順序排序:

with m as (
    select 
    ROW_NUMBER() over (partition by nameId order by email) as Nr, 
    email.NameId, email.Email 
    from email 
) 
select 
    name.NameId, 
    name.Name, 
    m1.Email as Mail1, 
    m2.Email as Mail2, 
    m3.Email as Mail3, 
    m4.Email as Mail4 
from name 
left join m m1 on (m1.Nr=1 and m1.NameId=name.NameId) 
left join m m2 on (m2.Nr=2 and m2.NameId=name.NameId) 
left join m m3 on (m3.Nr=3 and m3.NameId=name.NameId) 
left join m m4 on (m4.Nr=4 and m4.NameId=name.NameId) 
+0

我測試過了,它工作正常。謝謝 – user2974686

0

這不是漂亮,有使用的問題,等等,但如果你必須......你必須。所以,使用您的架構做法是: -

create function dbo.emails(@NameId int, @Ordinal int) 
returns varchar(1024) 
as begin 
    declare @returnValue varchar(1024) 
    select @returnValue=email 
    from (
     select 
      ROW_NUMBER() over (order by e.Email) as ordinal, 
      e.Email 
     from Email e 
     where [email protected] 
    ) p1 
    where [email protected] 
    return @returnValue 
end 
go 
select e.Name, 
    dbo.emails(n.NameId,1) as email1, 
    dbo.emails(n.NameId,2) as email2, 
    dbo.emails(n.NameId,3) as email3, 
    dbo.emails(n.NameId,4) as email4 
from Name n 
go 

生產: -

Name   email1     email2    email3     email4 
JOHN SMITH [email protected] [email protected]  [email protected]  NULL 
MARY SMITH [email protected]  NULL    NULL     NULL 
PHILL TAYLOR [email protected]   [email protected] [email protected] [email protected] 
+0

與plalx解決方案相同,在性能方面非常差。 –

+0

問題在哪裏提到高性能?有時你必須提供一個實用的解決方案。 – dav1dsm1th

+0

對我而言,不好的數據庫設計並不實用。用戶user2970362給出了一個執行得很好的實用解決方案。你已經實現的方式是錯誤的數據庫設計中的「排隊痛苦行」性能問題的確切範例。 –