Это может быть сделано в SQL через динамический sql, если вам нужно. Основная теория для того, чтобы сделать это для одного элемента (я буду использовать телефон), заключается в следующем: вы должны повторить это для каждой другой группы столбцов, которые вы хотите. Обратите внимание, что никто никогда не скажет, что это красиво.
- Создайте базовый запрос (CTE, таблица TEMP и т. Д.), Который получает идентификатор клиента, телефон для каждого действительного номера телефона. Добавьте число «ROW_NUMBER () OVER (PARTITION BY ClientID ORDER BY (что угодно))» - я назову его basedata
- Получите максимальный номер строки из basedata - это количество нужных вам телефонных столбцов
Создание частей строки динамического SQL-запроса с помощью цикла от i = 1 до MaxRowNo. В каждом цикле вы создаете строку выбора и строку соединения. Строка выбора должна добавить что-то вроде следующего в каждом цикле
Set @SelectStr = @SelectStr + 'P' + cast(i as varchar(10)) + '.Phone,';
Строка соединения должна добавлять что-то подобное в каждый цикл
Set @JoinStr = @JoinStr + ' left outer join baseData P' + cast(i as varchar(10)) + ' on P' + cast(i as varchar(10)) + '.ClientID = C.ClientID and P' + cast(i as varchar(10)) + '.RowNo = ' + cast(i as varchar(10));
Вы должны повторить весь вышеуказанный процесс для адресов и любых других повторяющихся групп столбцов - убедитесь, что вы не дублируете псевдонимы. Затем вы бы составили свой окончательный динамический SQL-запрос, добавив любые фиксированные, неизменные части запроса (данные клиента), что-то вроде этого
Set @FinalQuery = 'SELECT C.ClientID, C.ClientName, ' + @SelectStr + ' From Client C ' + @JoinStr
Ваш окончательный составленный запрос (при условии, что в качестве примера приводится максимум три телефона и два адреса) будет выглядеть примерно так - тогда EXEC эта строка
SELECT C.ClientID, C.ClientName, --any other client stuff you need here
P1.Phone, P2.Phone, P3.Phone, A1.Address, A2.Address
From Client C
left outer join baseData P1 on P1.ClientID = C.ClientID and P1.RowNo = 1
left outer join baseData P2 on P2.ClientID = C.ClientID and P2.RowNo = 2
left outer join baseData P3 on P3.ClientID = C.ClientID and P3.RowNo = 3
left outer join baseAddr A1 on A1.ClientID = C.ClientID and A1.RowNo = 1
left outer join baseAddr A2 on A2.ClientID = C.ClientID and A2.RowNo = 2