我有一个关于将列存储过程插入表的问题。 我有两个表约100行和1 Mil行。 基本上,我有一个函数返回int比较来自不同表的两个数据。 我想在每个数据组合上运行函数。
表1(~100行)
Col1
A
B
C
D
表2(~1 Mil行)
Col1
1
2
3
4
function(i,j)
其中i
来自表1,j
来自表2
简而言之,代码如下:
while i < count(*) table 1
print i
while j < count(*) table 2
select function(i,J)
J = J + 1
end
i = i + 1
j = 0
end
结果显示是一个长的单列,其中i(来自table1)和int从函数中计算。
i(1)
1
3
4
.
.
.
i(2)
1
2
.
.
我想显示上面的结果,如表动态地为i指定列名。
i(1) i(2) i(3) .....
1 1 5
3 2 9
4 3 4
提前致谢。
答案 0 :(得分:1)
这将是昂贵的,100,000,000结果!对于SQlserver的支持非常差。
要使用sp_crosstab(这不是任何人最需要做的事情列表的顶部),您需要三列
那就是'我','J'和f(i,j)
而不是while循环,你可以做通常是错误的事情。
选择Table1.Col1,Table2.Col1,Function(Table1.Col1,Table2.Col2) 从表1,表2
(或从Table1加入表2)
这为您提供了一个笛卡儿积,表1中的所有100条记录都连接到表2中的所有1,000,000条。 正确地将它传递给sp_crosstab,你将为Table2中的每个值geta row,Table1中每一行的一列,以及保存函数结果的单元格。
话虽如此,如果这有点慢,也不要感到惊讶,并且可能耗尽一点记忆......
你可能想尝试一些较小的范围。
答案 1 :(得分:0)
要获得所需的输出,请参阅下面的编码,我已完美编码,因此您只需要更改表名,并在代码块的注释区域中相应地调用您的函数。
DECLARE @rest INT,
@rev INT,
@counter INT,
@Table1Count INT,
@Table2Count INT
DECLARE @colName VARCHAR(50),
@Fields NVARCHAR(MAX),
@Sql VARCHAR(MAX)
SELECT @colName = 'Col', @Fields = '', @rest = 1, @rev = 1, @counter = 1
SELECT @Table1Count = count(*) from Table1
SELECT @Table2Count = count(*) from Table2
CREATE TABLE #temp (ID INT IDENTITY(1,1), defaultColumn VARCHAR(50))
WHILE @rest <= @Table2Count
BEGIN
INSERT INTO #temp (defaultColumn) VALUES(@rest)
SET @rest = @rest + 1
END
WHILE @counter <= @Table1Count
BEGIN
PRINT(CAST(@counter AS VARCHAR))
SET @colName = @colName+CAST(@counter AS VARCHAR)
SET @Fields = @Fields + @colName
IF @counter <> @Table1Count
BEGIN
SELECT @Fields = @Fields +', '
END
EXEC ('ALTER TABLE #temp ADD '+ @colName +' VARCHAR(250)')
WHILE @rev <= @Table2Count
BEGIN
-------------------------------------------------
-- Some modification may need to your Function
-- CALL YOUR FUNCTIN HERE
-------------------------------------------------
SET @Sql = 'UPDATE #temp SET '+ @colName +' = '+ CAST( @rev AS VARCHAR)
+' WHERE defaultColumn = '+ CAST( @rev AS VARCHAR)
EXEC (@Sql)
SET @rev = @rev + 1
END
SELECT @rev = 1, @counter = @counter +1, @colName = 'Col'
END
EXEC('SELECT '+ @Fields + ' FROM #temp')
DROP TABLE #temp
请记住,根据MSSQL服务器(您使用的版本),尝试使用低于表中最大允许列数的列。
希望这对你非常有帮助,谢谢你的时间
答案 2 :(得分:0)
这将是我的解决方案:
DECLARE @columns VARCHAR(MAX)
SELECT @columns = COALESCE(@columns + ',[' + CAST(t1.i as varchar(10)) + ']'
,'[' + CAST(t1.i as varchar(10)) + ']')
FROM t1
DECLARE @query VARCHAR(MAX)
SET @query = '
SELECT * FROM
(
SELECT t1.i, t2.j, yourFunction(t1.i, t2.j) as functionResult
FROM t1
CROSS JOIN t2
) as tbl3
PIVOT
(
SUM(functionResult) FOR i in (' + @columns + ')
) AS tblResults'
EXECUTE (@query)
您可以查看此here on SEDE的实际示例。
只是为了澄清,你会用你的2个表的实际名称替换t1和t2。同样在SEDE示例中,我刚刚将i
和j
加在一起(t1.i + t2.j as functionResult
),因为我无法在那里创建函数,但您只需调用您的函数,就像我在我的回答(yourFunction(t1.i, t2.j) as functionResult
)。