2008-09-30 3 views

ответ

3

Пример в http://jdixon.dotnetdevelopersjournal.com/pivot_table_data_in_sql_server_2000_and_2005.htm работает только в том случае, если вы заранее знаете, какие значения строк могут быть. Например, предположим, что у вас есть сущность с настраиваемыми атрибутами, а пользовательские атрибуты реализованы в виде строк в дочерней таблице, где дочерняя таблица в основном представляет собой пары переменных/значений, и эти пары переменных/значений настраиваются.

color red 
size big 
city Chicago 

Я собираюсь описать технику, которая работает. Я использовал его. Я НЕ продвигаю его, но он работает.

Чтобы развернуть данные, в которых вы не знаете, какие значения могут быть заранее, создайте временную таблицу «на лету» без столбцов. Затем используйте курсор для прокрутки строк, создавая динамически построенную «таблицу изменений» для каждой переменной, чтобы в конечном итоге ваша таблица temp имела столбцы, цвет, размер, город.

Затем вы вставляете одну строку в свою временную таблицу, обновляете ее с помощью другого курсора через пары переменных, значений и затем выбираете ее, как правило, соединяетесь с ее родительским сущностью, фактически создавая впечатление, что эти пользовательские пары переменных/значений были похожи на встроенные столбцы в исходном родительском объекте.

+2

Ссылка была нарушена :( – 2011-01-31 17:18:29

2

Описание метода курсора, вероятно, является наименее используемым SQL-кодом. Как уже упоминалось, SQL 2005 и on имеют PIVOT, который отлично работает. Но для более старых версий и серверов, отличных от MS SQL, метод Rozenshtein от «Оптимизация Transact-SQL» (редактирование: из печати, но с использованием Amazon: http://www.amazon.com/Optimizing-Transact-SQL-Advanced-Programming-Techniques/dp/0964981203) отлично подходит для поворота и разворота данных. Использует точечные характеристики для преобразования данных на основе строк в столбцы. Розенштейн описывает несколько случаев, вот один пример:

SELECT 
    RowValueNowAColumn = 
     CONVERT(varchar, 
      MAX(
      SUBSTRING(myTable.MyVarCharColumn,1,DATALENGTH(myTable.MyVarCharColumn) 
     * CHARINDEX(sa.SearchAttributeName,'MyRowValue')))) 
FROM 
    myTable 

Этот метод является гораздо более эффективным, чем использование заявлений тематических и работает для различных типов данных и реализаций SQL (не только MS SQL).

1

Лучшего ограничить малый масштаб для такого рода вещи. Если вы используете SQL 2k, хотя и не имеете доступных функций PIVOT, я разработал сохраненный процесс, который должен выполнить эту работу за вас. Немного работы с лихорадкой, так что потяните ее на сколько угодно. Вставьте нижеследующее в окно sql и отредактируйте EXEC внизу как предпочтительный.Если вы хотите увидеть, что генерируется, удалите в-S середине:

IF EXISTS (SELECT * FROM SYSOBJECTS WHERE XTYPE = 'P' AND NAME = 'USP_LIST_CONCAT') 
DROP PROCEDURE USP_LIST_CONCAT 
GO 

CREATE PROCEDURE USP_LIST_CONCAT (@SourceTable NVARCHAR(1000) = '' ,@SplitColumn NVARCHAR(1000) = '' , @Deli NVARCHAR(10) = '', @KeyColumns NVARCHAR(2000) = '' , @Condition NVARCHAR(1000) = '') 
AS 
BEGIN 
SET NOCOUNT ON 

/* PROCEDURE CREATED 2010 FOR SQL SERVER 2000. SIMON HUGHES. */ 
/* NOTES: REMOVE --'s BELOW TO LIST GENERATED SQL. */ 

IF @SourceTable = '' OR @SourceTable = '?' OR @SourceTable = '/?' OR @SplitColumn = '' OR @KeyColumns = '' 
BEGIN 
PRINT 'Format for use:' 
PRINT ' USP_LIST_CONCAT ''SourceTable'', ''SplitColumn'', ''Deli'', ''KeyColumn1,...'', ''Column1 = 12345 AND ...''' 
PRINT '' 
PRINT 'Description:' 
PRINT 'The SourceTable should contain a number of records acting as a list of values.' 
PRINT 'The SplitColumn should be the name of the column holding the values wanted.' 
PRINT 'The Delimiter may be any single character or string ie ''/''' 
PRINT 'The KeyColumn may contain a comma separated list of columns that will be returned before the concatenated list.' 
PRINT 'The optional Conditions may be left blank or may include the following as examples:' 
PRINT ' ''Column1 = 12334 AND (Column2 = ''ABC'' OR Column3 = ''DEF'')''' 
PRINT '' 
PRINT 'A standard list in the format:' 
PRINT ' Store1, Employee1, Rabbits' 
PRINT ' Store1, Employee1, Dogs' 
PRINT ' Store1, Employee1, Cats' 
PRINT ' Store1, Employee2, Dogs' 
PRINT '' 
PRINT 'Will be returned as:' 
PRINT ' Store1, Employee1, Cats/Dogs/Rabbits' 
PRINT ' Store1, Employee2, Dogs' 
PRINT '' 
PRINT 'A full ORDER BY and DISTINCT is included' 
RETURN -1 
END 


DECLARE @SQLStatement NVARCHAR(4000) 

SELECT @SQLStatement = ' 
DECLARE @DynamicSQLStatement NVARCHAR(4000) 

SELECT @DynamicSQLStatement = ''SELECT '[email protected]+', SUBSTRING('' 

SELECT @DynamicSQLStatement = @DynamicSQLStatement + '' + '' + CHAR(10) + 
'' MAX(CASE WHEN '[email protected]+' = ''''''+RTRIM('[email protected]+')+'''''' THEN '''''[email protected]+'''+RTRIM('[email protected]+')+'''''' ELSE '''''''' END)'' 
FROM '+ @SourceTable +' ORDER BY '[email protected]+' 

SELECT @DynamicSQLStatement = @DynamicSQLStatement + '' ,2,7999) List'' + CHAR(10) + ''FROM '+ @SourceTable+''' + CHAR(10) +'''+CASE WHEN @Condition = '' THEN '/* WHERE */' ELSE 'WHERE '[email protected] END+ '''+ CHAR(10) + ''GROUP BY '[email protected]+''' 

SELECT @DynamicSQLStatement = REPLACE(@DynamicSQLStatement,''(+'',''('') 

-- SELECT @DynamicSQLStatement -- DEBUG ONLY 
EXEC (@DynamicSQLStatement)' 

EXEC (@SQLStatement) 

END 
GO 

EXEC USP_LIST_CONCAT 'MyTableName', 'ColumnForListing', 'Delimiter', 'KeyCol1, KeyCol2', 'Column1 = 123456' 
0

У меня есть данные в следующем формате

Survey_question_ID

Email (User)

Ответ

на 1 опрос Есть 13 вопрос желаемый результат я хотел

Пользователь --- Survey_question_ID1 --- Survey_question_ID2

электронной почты --- отвечает - - ответ ........ и так далее

Вот решение для SQL Server 2000, Тип данных поля причины: ТЕКСТ.

DROP TABLE #tmp 

DECLARE @tmpTable TABLE 
(
emailno NUMERIC, 
question1 VARCHAR(80), 
question2 VARCHAR(80), 
question3 VARCHAR(80), 
question4 VARCHAR(80), 
question5 VARCHAR(80), 
question6 VARCHAR(80), 
question7 VARCHAR(80), 
question8 VARCHAR(80), 
question9 VARCHAR(80), 
question10 VARCHAR(80), 
question11 VARCHAR(80), 
question12 VARCHAR(80), 
question13 VARCHAR(8000) 
) 

DECLARE @tmpTable2 TABLE 
(
emailNumber NUMERIC 
) 

DECLARE @counter INT 
DECLARE @Email INT 

SELECT @counter =COUNT(DISTINCT ans.email) FROM answers ans WHERE ans.surveyname=100430 AND ans.qnpkey BETWEEN 233702 AND 233714 
SELECT * INTO #tmp FROM @tmpTable 
INSERT INTO @tmpTable2 (emailNumber) SELECT DISTINCT CAST(ans.email AS NUMERIC) FROM answers ans WHERE ans.surveyname=100430 AND ans.qnpkey BETWEEN 233702 AND 233714 

WHILE @counter >0 

BEGIN 

     SELECT TOP 1 @Email= emailNumber FROM @tmpTable2 
     INSERT INTO @tmpTable (emailno) VALUES (@Email) 


     Update @tmpTable set question1=CAST(answer as VARCHAR(80)) from answers ans where ans.surveyname=100430 and ans.qnpkey = 233702 and [email protected] 
     Update @tmpTable set question2=CAST(answer as VARCHAR(80)) from answers ans where ans.surveyname=100430 and ans.qnpkey = 233703 and [email protected] 
     Update @tmpTable set question3=CAST(answer as VARCHAR(80)) from answers ans where ans.surveyname=100430 and ans.qnpkey = 233704 and [email protected] 
     Update @tmpTable set question4=CAST(answer as VARCHAR(80)) from answers ans where ans.surveyname=100430 and ans.qnpkey = 233705 and [email protected] 
     Update @tmpTable set question5=CAST(answer as VARCHAR(80)) from answers ans where ans.surveyname=100430 and ans.qnpkey = 233706 and [email protected] 
     Update @tmpTable set question6=CAST(answer as VARCHAR(80)) from answers ans where ans.surveyname=100430 and ans.qnpkey = 233707 and [email protected] 
     Update @tmpTable set question7=CAST(answer as VARCHAR(80)) from answers ans where ans.surveyname=100430 and ans.qnpkey = 233708 and [email protected] 
     Update @tmpTable set question8=CAST(answer as VARCHAR(80)) from answers ans where ans.surveyname=100430 and ans.qnpkey = 233709 and [email protected] 
     Update @tmpTable set question9=CAST(answer as VARCHAR(80)) from answers ans where ans.surveyname=100430 and ans.qnpkey = 233710 and [email protected] 
     Update @tmpTable set question10=CAST(answer as VARCHAR(80)) from answers ans where ans.surveyname=100430 and ans.qnpkey = 233711 and [email protected] 
     Update @tmpTable set question11=CAST(answer as VARCHAR(80)) from answers ans where ans.surveyname=100430 and ans.qnpkey = 233712 and [email protected] 
     Update @tmpTable set question12=CAST(answer as VARCHAR(80)) from answers ans where ans.surveyname=100430 and ans.qnpkey = 233713 and [email protected] 
     Update @tmpTable set question13=CAST(answer as VARCHAR(8000)) from answers ans where ans.surveyname=100430 and ans.qnpkey = 233714 and [email protected] 

     insert into #tmp select * from @tmpTable  

     DELETE FROM @tmpTable  
     DELETE FROM @tmpTable2 WHERE emailNumber= @Email 

     set @counter [email protected] -1 

End 

select * from #tmp 
Смежные вопросы