如何将包含动态日期的报告作为T-SQL中的列。
我正在寻找像这样疯狂的代码。
希望它能帮助其他人。
如果有人知道更好的解决方案,请发帖。
DECLARE @columns VARCHAR(8000)
SELECT @columns = COALESCE(@columns + ',[' + convert(nvarchar(12), data, 103) + ']',
'[' + convert(nvarchar(12), data, 103)+ ']')
FROM Item
GROUP BY data
--print @columns
DECLARE @query VARCHAR(8000)
SET @query = '
;WITH G1 As
(
select id_item, convert(nvarchar(12), data, 103) as data, COUNT(*) as numar
from Item
group by id_item, data
)
SELECT *
FROM G1
PIVOT
(
sum(numar)
FOR [data]
IN (' + @columns + ')
) AS G2
'
print @query
EXECUTE(@query)
答案 0 :(得分:2)
对你问题中的例子做了几点评论。
使用QUOTENAME
而不是自己连接方括号。这将正确处理数据中的任何]
个字符。
您似乎在混合nvarchar
和varchar
。将动态SQL变量声明为NVARCHAR(MAX)
(如果定位SQL Server 2000,则为NVARCHAR(4000)
)而不是VARCHAR(8000)
。这意味着您的查询可以正确使用Unicode数据,并且在连接动态SQL时通常更安全。
(只是添加一个我为什么说这更安全的例子)
create table #t (a int, b char(1));
DECLARE @querystring varchar(max)
DECLARE @nquerystring nvarchar(max)
DECLARE @userinput nvarchar(100) = N'ʼ;Drop Table #t--'
IF @userinput LIKE '%''%'
BEGIN
RAISERROR('Possible SQL injection',16,1)
RETURN
END
SET @nquerystring = 'select * from #t where b = ''' + @userinput + ''''
exec (@nquerystring)
select OBJECT_ID('tempdb..#t') /*NOT NULL, Still There*/
SET @querystring = @nquerystring /*ʼ nchar(700) gets silently converted to a regular ' character*/
exec (@querystring)
select OBJECT_ID('tempdb..#t') /*NULL, Table Dropped*/
答案 1 :(得分:0)
这是一个静态版本(来自同事):
with c as (
select
p.id_doc,
p.id_usr,
DATEDIFF(DAY, p.created_at, getdate()) as date_diff
from Document p
where 1 = 1
), p as (
select
pvt.id_usr,
[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]
from c
PIVOT (COUNT(c.id_doc) FOR c.date_diff IN ([0], [1], [2], [3], [4], [5], [6], [7], [8], [9])) AS pvt
)
select
u.username,
u.name,
[0], [1], [2], [3], [4], [5], [6], [7], [8], [9],
y.nr,
y.total_money
from p
inner join Users u on u.id_usr = p.id_usr
cross apply (
select
COUNT(1) as nr,
SUM(premium) as total_money
from Document z
where z.id_usr = p.id_usr
) as y
order by nr desc