【发布时间】:2017-01-23 15:28:33
【问题描述】:
我正在尝试根据另一个临时表的行数构建一个具有动态列数的临时表。假设我在#table1 中有 89 行,在 #table2 我想使用行数并将相应的行值作为列名。我一直在摆弄这个,但我不断收到错误。这是我的查询,稍后将转换为 proc。
我的表看起来像这样(所有列都是 varchar,如果导入的日期没有该 CVE 编号的数据,则允许为空 - CVEId 与 CVENumber 表上的 FK 约束 CVEID 相关):
CVEId D20160901 D20160902 D20160903 D20160904 D20160905
1 6182 6473 5879 NULL NULL
2 72862 76583 NULL NULL 74772
CVENumber Table:
CVEID CVENumber
1 CVE-781-2016
2 CVE-006-2016
我希望获取列的日期,或者可能使用注入的日期作为第一行 - 对此数据运行查询,我可以指定 09-01-2016 到 09-03-2016。并从表中返回具有 CVENumber 表中引用的 CVENumber 的所有行。我希望我的结果如下所示:
CVE Number 09-01-2016 09-02-2016 09-03-2016
CVE-781-2016 6182 6473 8579
CVE-006-2016 72682 76583 0
我希望这能澄清我正在尝试做的事情。
我当前使用 STUFF() 的查询从 #FixedDates 中获取行并将其转换为列。我想将返回到@cols 的那些列作为列添加到#query_results
Set nocount on
Insert #tmp
EXEC sp_columns @table_name = N'CVECountsByDate'
-- Using collate to force the DB to only look at Uppercase values
DECLARE @cols varchar(max), @query varchar(max), @cols2 varchar(MAX)
INSERT #FixedDays
SELECT Replace(COLUMN_NAME, 'D' collate Latin1_General_CS_AS, '' collate Latin1_General_CS_AS) from #Tmp
WHERE COLUMN_NAME LIKE 'D%' collate Latin1_General_CS_AS OR COLUMN_NAME = 'CVEId' ORDER BY COLUMN_NAME DESC
SET @cols = STUFF((SELECT ',' + QUOTENAME(QT.COLUMN_NAME) + ' varchar(100)'
FROM #FixedDays QT
GROUP BY QT.COLUMN_NAME
ORDER BY QT.COLUMN_NAME
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)')
,1,1,'')
SET @cols2 = N'CREATE TABLE #query_results (' + @cols + ') '
--EXEC(@cols2)
SELECT @cols2
DROP TABLE #FixedDays
DROP TABLE #Tmp
【问题讨论】:
-
您为什么不希望它们成为行而不是新列?对于您需要对这些数据执行的任何其他操作,使用归一化的数据要容易得多。
-
这些列的格式 [不是我的设计] 类似于日期格式,但如下所示:列名称中的 2016 年 9 月 1 日为 D20160901。我正在尝试使用该列名并将其转换为 09-01-2016。存储过程用于创建报告。我正在寻找以正确格式创建日期的临时表,并为开始日期和结束日期传递两个参数。
-
这听起来像动态数据透视表或动态交叉表比尝试像这样调整临时表更好。
-
你知道我该怎么做吗?我对数据透视表不太强。 PIVOT 表能否将结果返回给我的报表查询?
-
这将是您报告的查询。这是一个很好的例子。 stackoverflow.com/questions/10404348/…
标签: sql-server temp-tables dynamicquery