Можно ли преобразовать строки в переменное количество столбцов в T-SQL? - PullRequest
0 голосов
/ 06 июля 2018

У меня странное требование, когда мне нужно преобразовать переменное количество строк в столбцы. Мне нужна помощь, чтобы выяснить, можно ли это сделать на SQL или просто написать программу на другом языке.

Давайте предположим, что у меня есть таблица Clients, которая содержит только минимальные данные клиента. Затем создается таблица под названием «Атрибуты», в которой указываются различные возможные атрибуты (скажем, номер телефона, адрес и т. Д.). Наконец, у меня есть третья таблица, ClientAttributes, которая содержит два FK и значение.

Так что для каждого клиента у меня есть любое количество атрибутов. Клиент может иметь ноль, 1 или бесконечные телефонные номера, ноль, 1 или бесконечные адреса и так далее.

Мне нужно табличное представление всех этих данных. Имя клиента, Телефон, Телефон 2, Телефон 3, ..., Адрес, Адрес 2, Адрес 3 .... и так далее. Если у клиента нет такого значения, значение будет нулевым. Очевидно, это означает, что число столбцов может отличаться при каждом выполнении запроса.

Это должно быть совместимо с SQL Server 2008.

Может ли это быть сделано исключительно в T-SQL или это нужно делать на стороне клиента, просто выгрузив данные и позволяя C # обрабатывать их? Я мог бы легко сделать это в C #, но я не уверен, что это можно сделать в SQL. SQL предпочтительнее, потому что набор данных может быть слишком большим, чтобы поместиться в оперативной памяти.

1 Ответ

0 голосов
/ 06 июля 2018

Это может быть сделано в 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...