Я работаю над запросом SQL, используя pvots с динамическими столбцами в SQL Server (T-sql).Вместо того, чтобы отправлять мой длинный запрос, я иллюстрирую свою проблему с помощью упрощенной модели.
Я создаю 2 таблицы: Table1 и Table2 и заполняю их несколькими записями следующим образом:
Table1:
Col_ID1 ............... Col_Name
1 ......................... янв-11
2 ......................... февраль-11
3 ......................... Mar-11
Table2:
Col_ID2 ...... Account .....AccountName ...... Сумма
1 ............... 121 ........... Электричество ............ 10000
2 ............... 121 ........... Электричество ............ 20000
3 ............... 121 ........... Электричество ............ 30000
1 ............... 122 ........... Телефон .............. 100
2 ............... 122 ........... Телефон .............. 200
3 ............... 122 ........... Телефон .............. 300
Я создаю сводную таблицу, но хочу, чтобы имена столбцов генерировались параметрически (на основе дат, введенных на экране ввода), и nне жестко закодировано.
Приведенный ниже запрос работает хорошо, но дает только несколько столбцов:
Янв-11 ........... Фев-11 ........... март-11
10 000,00 ...... 20 000,00 ...... 30 000,00
100,00 ............... 200,00 ........... 300,00
Я хочу, чтобы запрос также возвращал описательные столбцы, например:
Account........... AccountName ........... Jan-11 ............ февраль-11 .............. март-11
121 ................. Электричество .................10 000,00 ...... 20 000,00 .......... 30 000,00
122 ................. Телефон ..................... 100,00 ........... 200,00 ............. 300,00
Может ли кто-нибудь помочь мне изменить мой запрос, чтобы я мог достичь своей цели?
Этот запрос является адаптацией следующей статьи, написанной доктором Андрасом в сентябре 2007 года. http://www.simple -talk.com / community / blogs / andras / archive / 2007/09/14/37265.aspx
Кто-то заметил, что код может подвергаться атакам с помощью инъекций, и предложил использовать функцию Quotename вместо объединения квадратных скобок.
Не могли бы вы объяснить, как использовать Quotename в моем запросе.
Большое спасибо,
Леон Лай.
.
.
Вот мой запрос:
------------------------ создать и заполнить таблицу1 --------------------------------
CREATE TABLE Table1
(Col_ID1 INT,
Col_Name varchar(10))
INSERT INTO Table1 VALUES (1, 'Jan-11')
INSERT INTO Table1 VALUES (2, 'Feb-11')
INSERT INTO Table1 VALUES (3, 'Mar-11')
------------------------- создать и заполнить таблицу2 ----------------------------------
CREATE TABLE Table2
(Col_ID2 INT,
Account varchar(10),
AccountName varchar(20),
Amount numeric(18,6))
INSERT INTO Table2 VALUES (1, 121, 'Electricity', 10000)
INSERT INTO Table2 VALUES (2, 121, 'Electricity', 20000)
INSERT INTO Table2 VALUES (3, 121, 'Electricity', 30000)
INSERT INTO Table2 VALUES (1, 122, 'Telephone', 100)
INSERT INTO Table2 VALUES (2, 122, 'Telephone', 200)
INSERT INTO Table2 VALUES (3, 122, 'Telephone', 300)
---------------------------------- создать заголовки столбцов -------------------
DECLARE @cols NVARCHAR(2000)
SELECT @cols = STUFF(( SELECT DISTINCT TOP 100 PERCENT
'],[' + t2.Col_Name
FROM Table1 AS t2
ORDER BY '],[' + t2.Col_Name
FOR XML PATH('')
), 1, 2, '') + ']'
------------------------------------- create @query ----------------------
DECLARE @query NVARCHAR(4000)
SET @query = N'SELECT '+
@cols +'
FROM
-------------------------- подзапрос -----
(SELECT<br>
t1.Col_Name,<br>
t2.Account,<br>
t2.Amount<br>
FROM Table1 AS t1<br>
JOIN Table2 AS t2 ON t1.Col_ID1 = t2.Col_ID2<br>
) p
-------------------- pivot -------------------------
PIVOT<br>
(<br>
Sum ([Amount] )<br>
FOR Col_Name IN<br>
( '+<br>
@cols +' )<br>
) AS pvt '
---------------------- exec & drop ----------
EXECUTE(@query)
drop table table1
drop table table2
=======================================================
Привет, Филипп,
Большое спасибо за ваш ответ.
Ваш предложенный запрос работает без сбоев и создает ожидаемый экран, но это не совсем то, что я хотел.
Во-первых, спасибо за код: SELECT @cols = isnull (@cols + ',', '') + '[' + Col_Name + ']'
Это проще и заменяет мою строку, содержащую материал и путь XML, очевидно, с тем же эффектом.
Позвольте мне объяснить, что я хочу сделать.
Я хочу разработать запрос в Sap Business 1 (Пакет бухгалтерского учета - или назвать его ERP).Sap использует T-sql в Microsoft Server 2008 и имеет собственный генератор запросов.Сочень немногие исключения, Sap sql похож на T-sql.
Я хочу, чтобы мой запрос содержал список всех доходов и расходов ежемесячно за 12-месячный период.
Однако я не хочу, чтобы заголовки столбцов были жестко закодированы (поскольку это потребовало бы от меня время от времени вносить изменения в свой запрос) следующим образом:
11 января, 11 февраля, 11 марта, 11 апреля, ..... 11 декабря
Скорее, я хочу, чтобы заголовки столбцов создавались динамически из дат, которые пользователь вводит на экране ввода.
Как я уже упоминал, запрос, который я разместил на форуме, является упрощенной версией моего реального запроса и используется только для иллюстрации. Реальный запрос содержит несколько переменных, и экран ввода (называемый «Запрос - поле Критерии выбора» в Sap b1) позволяет пользователю ввести дату. Именно эта дата будет использоваться для динамического определения имен столбцов.
Именно поэтому мне понадобились такие сложные инструменты, как @cols, @query, pivot и т. Д.
Если я введу, скажем, «01 .06.11» (01 июня 2011 г.) на экране ввода, эта дата будет передана в sql, который определит названия заголовков столбцов следующим образом:
11 июня, 11 июля, 11 августа ... 12 мая.
Если я введу другую дату, скажем, «01 .09.10» (01 сентября 2010 г.), заголовки столбцов изменятся на:
сентябрь-10, октябрь-10, .... авг-11
Похоже, вы жестко закодировали заголовки моих столбцов.
Не могли бы вы еще раз взглянуть на мой запрос и предложить что-то, что позволит параметрически генерировать имена столбцов вместо жесткого кодирования?
Спасибо
Леон Лай