无法在 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)