2013-11-18 2 views
2

Я хочу объединить несколько строк в один столбец. Я нашел много примеров в Интернете, но не работает для меня. Что я делаю не так?Несколько строк в одном столбце SQL Server

 SELECT UserID, 
     STUFF((SELECT '; ' + Email.Email From Email where UserEmail.EmailID = Email.ID for xml path('')),1,1, '') AS Emails 
     From UserEmail 
     where UserID = 1 

Я все еще имея информацию, как этот

UserID Email 
1  [email protected] 
1  [email protected] 

--EDIT--

Хорошо, я сделал это изменение, но все еще с 2 строки. Если я применим различные, это исправит мою проблему, но почему я должен использовать разные. Запрос должен группировать его сам по себе.

 SELECT UserID, 
     STUFF((SELECT '; ' + ea.Email 
       From Email ea inner join UserMail ue_inner on ue_inner.EmailID = ea.ID 
       where 
       ue_inner.UserID = ue.UserID 
       for xml path('')), 1, 1, '') 
       AS Email 
     From UserEmail ue 
     where UserID = 1 

Результаты

UserID Email 
1  [email protected]; [email protected] 
1  [email protected]; [email protected] 

ответ

5

К сожалению, SQL Server не имеет надлежащую конкатенацию, так что вы не можете конкатенации строк в то время как группировки. Таким образом, существует несколько возможных решений.

1. Если вы хотите объединить данные для одного ID, вы можете использовать переменную трюк:

declare @Emails varchar(max) 

select @Emails = isnull(@Emails + ', ', '') + E.Email 
from Email as E 
    inner join UserEmail as UE on UE.EmailID = E.EmailID 
where UE.UserID = 1 

select @Emails; 

----------------- 
[email protected], [email protected] 

2. Если вы хотите сделать правильную группировку, вы можете использовать XML трюк. Итак, основная идея - вы получаете отдельный UserID как анкерный запрос (используя group by), а затем объединяете данные в подзапрос. Важно то, чтобы сделать это правильно, используйте for xml ... type и получить сцепленную строку в качестве .value(), поэтому специальные символы будут обрабатываться правильно:

select 
    UE.UserID, 
    stuff(
     (
      select ', ' + TE.Email 
      from Email as TE 
       inner join UserEmail as TUE on TUE.EmailID = TE.EmailID 
      where TUE.UserID = UE.UserID 
      for xml path(''), type 
     ).value('.', 'varchar(max)') 
    , 1, 2, '') as Emails 
from UserEmail as UE 
group by UE.UserID 

Смотрите SQL скрипку демо с примерами: sql fiddle demo

2

Весь суб-запрос внутри функции ВЕЩЕСТВО() вычисляется для каждой строки, которая удовлетворяет критериям в пункте где.

В этом случае вы, кажется, есть две строки с идентификатором 1.

Поскольку результаты, которые вы хотите являются для всего набора, каждая строка в этом наборе будет иметь те же результаты, поэтому выбор отличается только помогает скрыть дубликаты.

При форматирования вашего запроса, как это, будет легче понять, почему это происходит:

SELECT 
    UserID, 
    STUFF((SELECT '; ' + ea.Email 
      From Email ea inner join UserMail ue_inner on ue_inner.EmailID = ea.ID 
      where 
      ue_inner.UserID = ue.UserID 
      for xml path('')), 1, 1, '') AS Email, 
    ue.Email 
From UserEmail ue 
where UserID = 1 
Смежные вопросы