无法在 table 中保存动态交叉表
Can't save dynamic crosstab in table
我一直在使用 Access 进行一些简单的查询,但随着数据和查询复杂性的增加,我不得不开始使用 MSSQL。
我一直在通过反复试验和咨询 Whosebug 来学习 MSSQL,但我想不出一种方法来克服我最近的墙。
我需要动态构建交叉表,但我一直无法将数据保存在 table。
为了简洁起见,我缩短了以下查询:
1 IF OBJECT_ID('#TEMPF','U') IS NOT NULL DROP TABLE #TEMPF
2 IF OBJECT_ID('#TEMPUF','U') IS NOT NULL DROP TABLE #TEMPUF
3 IF OBJECT_ID('#TEMPVAR','U') IS NOT NULL DROP TABLE #TEMPVAR
4
5 SELECT * INTO #TEMPF FROM ...
6 SELECT ROW_NUMBER() OVER (...) AS ID, * INTO #TEMPUF FROM ...
7
8 DECLARE @TCMAX ...
9 DECLARE @INCREMENT MONEY ...
10
11 SELECT * INTO #TEMPVAR FROM #TEMPUF CROSS APPLY ...
12
13 DECLARE @TCUB ...
14 DECLARE @TCLB ...
15 DECLARE @LABEL NVARCHAR(...)
16 DECLARE @CMD NVARCHAR(MAX)
17 DECLARE @NUM ...
18
19 WHILE (@TCLB <= @TCMAX) BEGIN
20 SET @LABEL = ...
21 SET @CMD = N'DECLARE @INCREMENT MONEY = ' + CONVERT(NVARCHAR(...),@INCREMENT,1) + N'
22 ALTER TABLE #TEMPUF
23 ADD ' + @LABEL + N' FLOAT
24 INSERT INTO #TEMPUF (' + @LABEL + N')
25 SELECT ' + @LABEL + N'
26 FROM #TEMPVAR
27 CROSS APPLY
28 (SELECT ... AS ' + @LABEL + N' FROM #TEMPF
29 WHERE ...) AS ALIAS'
30 EXEC(@CMD)
31 SET @TCUB += ...
32 SET @TCLB += ...
33 SET @NUM += ...
34 END
35
36 SELECT * FROM #TEMPUF
37
38 DROP TABLE #TEMPF
39 DROP TABLE #TEMPUF
40 DROP TABLE #TEMPVAR
41 GO
以上查询抛出无效的列名错误消息。
我尝试将 @cmd [第 21-29 行] 分成 2 个 @cmds,第一个是 alter 命令 [第 22-23 行](成功),第二个是插入命令 [第 24-29 行](失败)。
我还尝试通过在外部执行插入命令来进一步划分第二个@cmd。尽管 select 命令 [第 25-29 行] 运行良好,但 SQL 已抛出相同的无效列名错误消息。
这显然是插入命令中的一个问题,但是通过执行 #TEMPUF 的 select 命令,我检查了正在添加的列。我想不出解决办法。
感谢您的帮助!
1 DECLARE @INCREMENT MONEY ...
2 INSERT INTO #TEMPUF (BIN1)
3 SELECT BIN1 FROM #TEMPVAR
4 CROSS APPLY
5 (SELECT COALESCE(CAST(COUNT(DISTINCT CONT) AS FLOAT)/NULLIF(CAST(#TEMPVAR.DCTC AS FLOAT)
6 , 0.0), 0.0) AS BIN1
7 FROM #TEMPF
8 WHERE ...) AS ALIAS
千辛万苦找到了解决问题的办法
虽然它仍然很难看,但我已经从插入命令更改为更新命令。
我使用了 ID 列,因为#TEMPVAR 是从#TEMPUF 创建的。
下面是修改后的@CMD。
感谢大家付出的时间和努力!
21 SET @CMD = N'DECLARE @INCREMENT MONEY = ' + CONVERT(NVARCHAR(...), @INCREMENT, 0) + N';
22 WITH SHADOW AS (SELECT ID, ' + @LABEL + N' FROM #TEMPVAR
23 CROSS APPLY
24 (SELECT ... AS ' + @LABEL + N'
25 FROM #TEMPF
26 WHERE ...) AS ALIAS)
27 UPDATE #TEMPUF
28 SET ' + @LABEL + N' = SHADOW.' + @LABEL + '
29 FROM SHADOW
30 WHERE #TEMPUF.ID = SHADOW.ID'
31 EXEC(@CMD)
我一直在使用 Access 进行一些简单的查询,但随着数据和查询复杂性的增加,我不得不开始使用 MSSQL。 我一直在通过反复试验和咨询 Whosebug 来学习 MSSQL,但我想不出一种方法来克服我最近的墙。
我需要动态构建交叉表,但我一直无法将数据保存在 table。
为了简洁起见,我缩短了以下查询:
1 IF OBJECT_ID('#TEMPF','U') IS NOT NULL DROP TABLE #TEMPF
2 IF OBJECT_ID('#TEMPUF','U') IS NOT NULL DROP TABLE #TEMPUF
3 IF OBJECT_ID('#TEMPVAR','U') IS NOT NULL DROP TABLE #TEMPVAR
4
5 SELECT * INTO #TEMPF FROM ...
6 SELECT ROW_NUMBER() OVER (...) AS ID, * INTO #TEMPUF FROM ...
7
8 DECLARE @TCMAX ...
9 DECLARE @INCREMENT MONEY ...
10
11 SELECT * INTO #TEMPVAR FROM #TEMPUF CROSS APPLY ...
12
13 DECLARE @TCUB ...
14 DECLARE @TCLB ...
15 DECLARE @LABEL NVARCHAR(...)
16 DECLARE @CMD NVARCHAR(MAX)
17 DECLARE @NUM ...
18
19 WHILE (@TCLB <= @TCMAX) BEGIN
20 SET @LABEL = ...
21 SET @CMD = N'DECLARE @INCREMENT MONEY = ' + CONVERT(NVARCHAR(...),@INCREMENT,1) + N'
22 ALTER TABLE #TEMPUF
23 ADD ' + @LABEL + N' FLOAT
24 INSERT INTO #TEMPUF (' + @LABEL + N')
25 SELECT ' + @LABEL + N'
26 FROM #TEMPVAR
27 CROSS APPLY
28 (SELECT ... AS ' + @LABEL + N' FROM #TEMPF
29 WHERE ...) AS ALIAS'
30 EXEC(@CMD)
31 SET @TCUB += ...
32 SET @TCLB += ...
33 SET @NUM += ...
34 END
35
36 SELECT * FROM #TEMPUF
37
38 DROP TABLE #TEMPF
39 DROP TABLE #TEMPUF
40 DROP TABLE #TEMPVAR
41 GO
以上查询抛出无效的列名错误消息。 我尝试将 @cmd [第 21-29 行] 分成 2 个 @cmds,第一个是 alter 命令 [第 22-23 行](成功),第二个是插入命令 [第 24-29 行](失败)。 我还尝试通过在外部执行插入命令来进一步划分第二个@cmd。尽管 select 命令 [第 25-29 行] 运行良好,但 SQL 已抛出相同的无效列名错误消息。
这显然是插入命令中的一个问题,但是通过执行 #TEMPUF 的 select 命令,我检查了正在添加的列。我想不出解决办法。
感谢您的帮助!
1 DECLARE @INCREMENT MONEY ...
2 INSERT INTO #TEMPUF (BIN1)
3 SELECT BIN1 FROM #TEMPVAR
4 CROSS APPLY
5 (SELECT COALESCE(CAST(COUNT(DISTINCT CONT) AS FLOAT)/NULLIF(CAST(#TEMPVAR.DCTC AS FLOAT)
6 , 0.0), 0.0) AS BIN1
7 FROM #TEMPF
8 WHERE ...) AS ALIAS
千辛万苦找到了解决问题的办法
虽然它仍然很难看,但我已经从插入命令更改为更新命令。 我使用了 ID 列,因为#TEMPVAR 是从#TEMPUF 创建的。 下面是修改后的@CMD。
感谢大家付出的时间和努力!
21 SET @CMD = N'DECLARE @INCREMENT MONEY = ' + CONVERT(NVARCHAR(...), @INCREMENT, 0) + N';
22 WITH SHADOW AS (SELECT ID, ' + @LABEL + N' FROM #TEMPVAR
23 CROSS APPLY
24 (SELECT ... AS ' + @LABEL + N'
25 FROM #TEMPF
26 WHERE ...) AS ALIAS)
27 UPDATE #TEMPUF
28 SET ' + @LABEL + N' = SHADOW.' + @LABEL + '
29 FROM SHADOW
30 WHERE #TEMPUF.ID = SHADOW.ID'
31 EXEC(@CMD)