我正在使用pvots与SQL Server(T-sql)中的动态列进行SQL查询。 而不是提交我冗长的查询,我用简化的模型来说明我的问题。在SQL Server中使用动态列的枢轴
我创建2个表:表1和表2,并用几个条目填充这些如下:
表1:
Col_ID1 ............ ... COL_NAME
1 .........................月11
2 ........ ................. Feb-11
3 ......................... 3月-11
表2:
Col_ID2 ......账户.....账户名......金额
1 ............... 121 ......... ..Electricity ............ 10000
2 ............... 121 ...........电。 ........... 20000
3 ............... 121 ...........电力............ 30000
1 ............... 122 ...........电话.............. 100
2。 .............. 122 ...........电话.............. 200
3 ... ............ 122 ...........电话.............. 300
我正在创建一个枢轴,但我想要参数化地生成列名(基于从输入s键入的日期creen),而不是硬编码。
下面的查询效果很好,但仅提供了一些列的FOLL:
月11 ...........月11 ........ ...... 3月-11
10,000.00 20,000.00 ...... 30,000.00 ......
100.00 200.00 ............... .... ....... 300.00
我希望查询也返回描述性列,如下所示:
帐户...........帐户名........... 1月11日............ 2月11日.. ............ Mar-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
------------------------ --subquery -----
(SELECT
t1.Col_Name,
t2.Account,
t2.Amount
FROM Table1 AS t1
JOIN Table2 AS t2 ON t1.Col_ID1 = t2.Col_ID2
) p
--------------------枢轴------------ -------------
PIVOT
(
Sum ([Amount])
FOR Col_Name IN
('+
@cols +')
) AS pvt '
---------------------- EXEC &下降----------
EXECUTE(@query)
drop table table1
drop table table2
=== ================================================== ==
菲利普嗨,
非常感谢您的回复。
您提出的查询工作顺利,并生成期望的屏幕,但它不完全是我想要的。
首先,感谢的代码: SELECT @cols = ISNULL(@cols + '', '')+ '[' + COL_NAME + ']'
这是简单和不替换我线涉及到东西和XML路径,显然具有相同的效果。
让我解释我想要做什么。
我想在SAP业务1(会计软件包 - 或称之为ERP)中开发查询。 Sap在Microsoft Server 2008中使用T-sql,并拥有自己的查询生成器。 除了极少数例外,Sap sql与T-sql类似。
我希望我的查询能够在12个月内逐月列出所有收入和支出。
不过,我不希望被硬编码我的列标题,(因为这需要我不时修改我的查询)如下:
扬11月11,Mar- 11,Apr-11,... Dec-11
相反,我希望列标题是从用户在输入屏幕中输入的日期动态生成的。
正如我所提到的,我在论坛上发布的查询是我的真实查询的过度简化版本,仅用于说明。真正的查询包含多个变量和一个输入屏幕(在Sap b1中称为查询 - 选择标准框)允许用户输入日期。这是将用于动态确定列名称的日期。
这就是为什么我需要这样复杂的工具@cols,@query,旋转等
如果我输入,说'01 .06.11' (2011年6月1日)在输入画面中,该日期将被传递给sql,它将确定列标题的名称为foll:
Jun-11,Jul-11,Aug-11 ..... May-12。
如果我输入另一个日期,说'01 .09.10' (2010年9月1日),列标题将变为:
九月10,2010年10月,... 8 - 11
看来你已经硬编码了我的列标题。
您能否再次查看我的查询,并提出一些允许以参数方式生成列名而不是硬编码的内容?
感谢
黎明
嗨菲利普,我发布了一个问题到您的回复谢谢莱昂 –
这是一个可笑的很好的答案! – jTC
使用'quotename(Col_Name)'而不是''['+ Col_Name +']''。 – jnm2