Sql server 基于另一个临时表中的行,动态地将列添加到临时表中
我试图根据另一个临时表的行数,构建一个列数动态的临时表。假设我在#表1中有89行,在#表2中,我想使用行计数并将相应的行值作为列名。我已经摆弄这个有一段时间了,但我不断地出错。这是我的查询,稍后将转换为proc 我的表如下所示(所有列都是varchar,如果导入的日期没有该CVE编号的数据,则允许为null-CVEId与CVENumber表上的FK约束CVEId相关): 我希望得到的是列的日期,或者可能使用注入日期作为第一行-对该数据运行查询,其中我可以指定09-01-2016到09-03-2016。并返回带有CVENumber表中引用的CVENumber的表中的所有行。我希望我的结果是什么样的:Sql server 基于另一个临时表中的行,动态地将列添加到临时表中,sql-server,temp-tables,dynamicquery,Sql Server,Temp Tables,Dynamicquery,我试图根据另一个临时表的行数,构建一个列数动态的临时表。假设我在#表1中有89行,在#表2中,我想使用行计数并将相应的行值作为列名。我已经摆弄这个有一段时间了,但我不断地出错。这是我的查询,稍后将转换为proc 我的表如下所示(所有列都是varchar,如果导入的日期没有该CVE编号的数据,则允许为null-CVEId与CVENumber表上的FK约束CVEId相关): 我希望得到的是列的日期,或者可能使用注入日期作为第一行-对该数据运行查询,其中我可以指定09-01-2016到09-03-20
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_结果中
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
这就是我最后做的
CREATE TABLE #Tmp
(TABLE_QUALIFIER varchar(40),
TABLE_OWNER varchar(20),
TABLE_NAME varchar(40),
COLUMN_NAME varchar(40),
DATA_TYPE int,
TYPE_NAME varchar(20),
PREC int, LENGTH int,
SCALE int, RADIX int,
NULLABLE char(4),
REMARKS varchar(128),
COLUMN_DEF varchar(40),
SQL_DATA_TYPE int,
SQL_DATETIME_SUB int,
CHAR_OCTET_LENGTH int,
ORDINAL_POSITION int,
IS_NULLABLE char(4),
SS_DATA_TYPE int)
CREATE TABLE #FixedDays
(COLUMN_NAME varchar(40))
CREATE TABLE #query_results
(CVENumber varchar(100) null)
Set nocount on
Insert #tmp
EXEC sp_columns @table_name = N'CVECountsByDate'
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'
DECLARE @listStr VARCHAR(MAX)
DECLARE @FixedList VARCHAR(MAX)
SELECT @FixedList = COALESCE(@FixedList,'[') + COLUMN_NAME + '] VARCHAR(MAX) NULL, [' FROM #FixedDays
SELECT @FixedList = substring(@FixedList, 1, len(@FixedList) -1)
SET @FixedList = LEFT(@FixedList, len(@FixedList)-1) -- Altered Column List
EXEC(N'ALTER TABLE #query_results ADD ' + @FixedList + '')
INSERT INTO #query_results
SELECT CVEDetails.CVENumber, CVECountsByDate.* FROM CVECountsByDate INNER JOIN CVEDetails ON CVECountsByDate.CVEId = CVEDetails.CVEID
ALTER TABLE #query_results DROP column CVEId
DROP TABLE #query_results
DROP TABLE #Tmp
DROP TABLE #FixedDays
为什么不希望这些是行而不是新列?使用规范化数据对于处理此数据所需的任何其他操作都要容易得多。这些列的格式[不是我的设计]类似于日期格式,但如下所示:列名称中的2016年9月1日是D20160901。我正在尝试将该列名称转换为09-01-2016。存储过程用于创建报告。我正在寻找以正确的格式创建带有日期的临时表,并为开始日期和结束日期传递两个参数。这听起来像是一个动态轴心或动态交叉表会是一个比尝试调整这样的临时表更好的解决方案。你有什么想法吗?我对透视表不是很在行。数据透视表能否将结果返回到“我的报告”查询?它将是对您的报告的查询。这是一个很好的例子。
CREATE TABLE #Tmp
(TABLE_QUALIFIER varchar(40),
TABLE_OWNER varchar(20),
TABLE_NAME varchar(40),
COLUMN_NAME varchar(40),
DATA_TYPE int,
TYPE_NAME varchar(20),
PREC int, LENGTH int,
SCALE int, RADIX int,
NULLABLE char(4),
REMARKS varchar(128),
COLUMN_DEF varchar(40),
SQL_DATA_TYPE int,
SQL_DATETIME_SUB int,
CHAR_OCTET_LENGTH int,
ORDINAL_POSITION int,
IS_NULLABLE char(4),
SS_DATA_TYPE int)
CREATE TABLE #FixedDays
(COLUMN_NAME varchar(40))
CREATE TABLE #query_results
(CVENumber varchar(100) null)
Set nocount on
Insert #tmp
EXEC sp_columns @table_name = N'CVECountsByDate'
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'
DECLARE @listStr VARCHAR(MAX)
DECLARE @FixedList VARCHAR(MAX)
SELECT @FixedList = COALESCE(@FixedList,'[') + COLUMN_NAME + '] VARCHAR(MAX) NULL, [' FROM #FixedDays
SELECT @FixedList = substring(@FixedList, 1, len(@FixedList) -1)
SET @FixedList = LEFT(@FixedList, len(@FixedList)-1) -- Altered Column List
EXEC(N'ALTER TABLE #query_results ADD ' + @FixedList + '')
INSERT INTO #query_results
SELECT CVEDetails.CVENumber, CVECountsByDate.* FROM CVECountsByDate INNER JOIN CVEDetails ON CVECountsByDate.CVEId = CVEDetails.CVEID
ALTER TABLE #query_results DROP column CVEId
DROP TABLE #query_results
DROP TABLE #Tmp
DROP TABLE #FixedDays