РЕДАКТИРОВАТЬ: см. Примечание внизу для более подробной информации.
Я столкнулся с той же проблемой, и я нашел решение, которое медленно. Может быть, у кого-то есть решение для ускорения моих выводов. В моем коде у меня есть таблица с тремя столбцами: Col1, Col2, Col3. Col1 мой идентификатор записи. Col2 - это имя моих динамических столбцов. Col3 - это значение в этом столбце. Поэтому, если бы я хотел представить запись с идентификатором 1, двумя столбцами 2 и 3 и значениями в этих столбцах: 4 и 5, у меня было бы следующее:
Col1, Col2, Col3
1, 2, 4
1, 3, 5
Затем мы поворачиваемся над столбцом 2 и выбираем MAX (или MIN, или AVG, не имеет значения, поскольку комбинации col2 и col3 уникальны) col3 в сводной таблице. Чтобы выполнить сводку с переменным числом столбцов, мы используем динамическое генерирование SQL для генерации нашего SQL. Это хорошо работает для небольших входных данных (я полагаю, производная таблица внутри предложения FROM динамического SQL). Как только ваш набор данных станет большим, выполнение средней функции займет много времени. Очень долгое время. Похоже, это начинается примерно с 1000 строк, так что, возможно, есть подсказка или другой метод, который делает это короче.
Как примечание, поскольку значения для Col2 и Col3 отображаются 1: 1, я также попытался динамически сгенерировать оператор SELECT, как показано ниже:
SELECT Col1,
CASE WHEN Col2 = '4' THEN Col3 END [4],
CASE WHEN Col2 = '5' THEN Col3 END [5],
CASE WHEN Col2 = '6' THEN Col3 END [6], -- ... these were dyanmically generated
FROM #example
GROUP BY Col1
Это было так же медленно для моего набора данных. Ваша миля может отличаться. Вот полный пример того, как это работает, написанный для SQL Server (2005+ должен запускать это).
--DROP TABLE #example
CREATE TABLE #example
(
Col1 INT,
Col2 INT,
Col3 INT
)
INSERT INTO #example VALUES (2,4,10)
INSERT INTO #example VALUES (2,5,20)
INSERT INTO #example VALUES (2,6,30)
INSERT INTO #example VALUES (2,7,40)
INSERT INTO #example VALUES (2,8,50)
INSERT INTO #example VALUES (3,4,11)
INSERT INTO #example VALUES (3,5,22)
INSERT INTO #example VALUES (3,6,33)
INSERT INTO #example VALUES (3,7,44)
INSERT INTO #example VALUES (3,8,55)
DECLARE @columns VARCHAR(100)
SET @columns = ''
SELECT @columns = @columns + '[' + CAST(Col2 AS VARCHAR(10)) + '],'
FROM (SELECT DISTINCT Col2 FROM #Example) a
SELECT @columns = SUBSTRING(@columns, 0, LEN(@columns) )
DECLARE @dsql NVARCHAR(MAX)
SET @dsql = '
select Col1, ' + @columns + '
from
(select Col1, Col2, Col3 FROM #example e) a
PIVOT
(
MAX(Col3)
FOR Col2 IN (' + @columns + ')
) p'
print @dsql
EXEC sp_executesql @dsql
РЕДАКТИРОВАТЬ: из-за уникальной ситуации, в которой я это делаю, мне удалось ускорить работу с использованием двух таблиц (одна с сущностями, а другая с парами атрибут-значение) и создания кластеризованного индекса на пары атрибут-значение, которые включают все столбцы (идентификатор, атрибут, значение). Я рекомендую вам обойти этот подход другим способом, если вам нужны быстрые вставки, большое количество столбцов, много строк данных и т. Д. У меня есть некоторые известные уверенности относительно размера и темпов роста моих данных, и мое решение подходит для моей области ,
Существует много других решений, которые лучше подходят для решения этой проблемы. Например, если вам нужны быстрые вставки и чтение одной записи (или медленное чтение не имеет значения), вам следует рассмотреть возможность упаковки строки XML в поле и сериализации / десериализации в потребителе базы данных. Если вам нужны сверхбыстрые записи, сверхбыстрые операции чтения и столбцы данных, которые добавляются очень редко, вы можете подумать об изменении таблицы. Это плохое решение в большинстве случаев, но может соответствовать некоторым проблемам. Если у вас есть столбцы, которые меняются достаточно часто, но вам также нужны быстрые операции чтения и записи, тогда мое решение может работать для вас до определенного размера набора данных.