2013-11-09 2 views
2

У меня есть два нормированные Server 2008 таблица SQL, один для имен и другое для писем:Таблицы сервера Денормализовать SQL

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] 

Возможно ли использовать один выбор?

Любые идеи будут очень признательны

Тиа

Ricardo Ногейра

+0

Будет ли разделяемая запятая информация выполнять эту работу? Это намного проще .. –

+0

Вы предлагаете, чтобы все, если имена совпадают, тогда адреса электронной почты относятся к одному и тому же человеку? Это не соответствует действительности, если вы не ограничиваете ее каким-то (неявным в вопросе) критерием. –

+0

Что вы подразумеваете под предопределенным расположением? Я имею в виду, каков ваш предопределенный макет? Будет ли запятонный список писем в порядке исключения? –

ответ

2

Это можно сделать в 1 выбрать. Если вы хотите только первые 4 адреса электронной почты и использовать их в качестве конкретных столбцов. Используйте функцию RowNumber в таблице электронной почты, чтобы набирать адрес электронной почты для каждого пользователя. В этом примере предполагается, что адреса электронной почты должны быть отсортированы в алфавитном порядке:

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 дал прагматичное решение, которое тоже хорошо работает. То, как вы его реализуете, является точной парадигмой проблемы производительности «строка по агонистической строке» плохого проектирования базы данных. –

Смежные вопросы