以 SQL 方式实施存储过程迭代方法
Implement the stored procedure iterative approach in a SQL manner
我正在尝试实现两个向量 v1 和 v2 之间的卷积。作为其中的一部分,我编写了一个使用 while 循环的迭代方法的存储过程。下面是下面的代码。我无法考虑如何使用 SQL 来完成它,因为存储过程效率低下 w.r.t 性能。有人可以分享您对此的看法吗?如有任何意见,我们将不胜感激。
编写存储过程的思路:
https://software.intel.com/en-us/ipp-dev-reference-convolve
Table 架构和示例输入数据:
CREATE TABLE AIRWork..TableA (idx INT, val INT);
CREATE TABLE AIRWork..TableB (idx INT, val INT);
INSERT INTO AIRWork..TableA
VALUES (0, -2), (1, 0), (2, 1), (3, -1), (4, 3);
INSERT INTO AIRWork..TableB
VALUES (0, 0), (1, 1);
存储过程:
ALTER PROCEDURE Calc_Convolved_Values_Test
AS
BEGIN
DECLARE @srclen1 INT
DECLARE @srclen2 INT
DECLARE @n INT = 0
DECLARE @k INT
DECLARE @m INT
DECLARE @SQL NVARCHAR(1000)
DECLARE @x int
DECLARE @xx int = 0
DECLARE @sum INT = 0
DECLARE @y int
DECLARE @yy int = 0
DECLARE @a INT = 0
DECLARE @b INT = 0
SELECT @srclen1 = COUNT(*) FROM AIRWork..TableA;
SELECT @srclen2 = COUNT(*) FROM AIRWork..TableB;
SET @m = @srclen1 + @srclen2 -1
WHILE @n < @m
BEGIN
SET @k = 0
SET @sum = 0
WHILE @k <= @n
BEGIN
SET @SQL = 'SELECT @x=val FROM AIRWork..TableA WHERE idx ='+CONVERT(VARCHAR(5),@k)
EXEC sp_executesql @SQL, N'@x int out', @xx out
SET @a = @xx
IF @n-@k < @srclen2
BEGIN
SET @SQL = 'SELECT @y=val FROM AIRWork..TableB WHERE idx ='+CONVERT(VARCHAR(5),@n-@k)
EXEC sp_executesql @SQL, N'@y int out', @yy out
SET @b = @yy
END
ELSE
BEGIN
SET @b = 0
END
SET @sum = @sum + @a*@b
SET @k = @k + 1
END
PRINT @sum
SET @n = @n + 1
END
END
GO
示例输出:
pDst[n] --> 请检查问题开头的公式
0
-2
0
1
-1
3
这个程序应该可以做到:
ALTER PROCEDURE Calc_Convolved_Values_Test
AS
;WITH AllRows AS
(
SELECT idx, val, 0 as tbl FROM AIRWork..TableA
UNION ALL SELECT idx, val, 1 as tbl FROM AIRWork..TableB
)
, CombinedRows As
(
SELECT *,
ROW_NUMBER() OVER(ORDER BY tbl, idx)-1 As k,
COUNT(*) OVER(PARTITION BY 1) - 1 As n
FROM AllRows
)
SELECT ABDest.k As idx, SUM(A.val * B.val) As val
FROM CombinedRows AS ABDest
JOIN CombinedRows AS AB ON AB.k <= ABDest.k
LEFT JOIN AIRWork..TableA As A ON A.idx = AB.k
LEFT JOIN AIRWork..TableB As B ON B.idx = ABDest.k - AB.k
WHERE ABDest.k < ABDest.n
GROUP BY ABDest.k
ORDER BY ABDest.k
GO
仅供参考,我不建议使用整个 table 来存储单个向量。最好将所有向量存储在同一个 table 中并使用名称或 ID 键列来分隔它们。
我正在尝试实现两个向量 v1 和 v2 之间的卷积。作为其中的一部分,我编写了一个使用 while 循环的迭代方法的存储过程。下面是下面的代码。我无法考虑如何使用 SQL 来完成它,因为存储过程效率低下 w.r.t 性能。有人可以分享您对此的看法吗?如有任何意见,我们将不胜感激。
编写存储过程的思路:
https://software.intel.com/en-us/ipp-dev-reference-convolve
Table 架构和示例输入数据:
CREATE TABLE AIRWork..TableA (idx INT, val INT);
CREATE TABLE AIRWork..TableB (idx INT, val INT);
INSERT INTO AIRWork..TableA
VALUES (0, -2), (1, 0), (2, 1), (3, -1), (4, 3);
INSERT INTO AIRWork..TableB
VALUES (0, 0), (1, 1);
存储过程:
ALTER PROCEDURE Calc_Convolved_Values_Test
AS
BEGIN
DECLARE @srclen1 INT
DECLARE @srclen2 INT
DECLARE @n INT = 0
DECLARE @k INT
DECLARE @m INT
DECLARE @SQL NVARCHAR(1000)
DECLARE @x int
DECLARE @xx int = 0
DECLARE @sum INT = 0
DECLARE @y int
DECLARE @yy int = 0
DECLARE @a INT = 0
DECLARE @b INT = 0
SELECT @srclen1 = COUNT(*) FROM AIRWork..TableA;
SELECT @srclen2 = COUNT(*) FROM AIRWork..TableB;
SET @m = @srclen1 + @srclen2 -1
WHILE @n < @m
BEGIN
SET @k = 0
SET @sum = 0
WHILE @k <= @n
BEGIN
SET @SQL = 'SELECT @x=val FROM AIRWork..TableA WHERE idx ='+CONVERT(VARCHAR(5),@k)
EXEC sp_executesql @SQL, N'@x int out', @xx out
SET @a = @xx
IF @n-@k < @srclen2
BEGIN
SET @SQL = 'SELECT @y=val FROM AIRWork..TableB WHERE idx ='+CONVERT(VARCHAR(5),@n-@k)
EXEC sp_executesql @SQL, N'@y int out', @yy out
SET @b = @yy
END
ELSE
BEGIN
SET @b = 0
END
SET @sum = @sum + @a*@b
SET @k = @k + 1
END
PRINT @sum
SET @n = @n + 1
END
END
GO
示例输出:
pDst[n] --> 请检查问题开头的公式
0
-2
0
1
-1
3
这个程序应该可以做到:
ALTER PROCEDURE Calc_Convolved_Values_Test
AS
;WITH AllRows AS
(
SELECT idx, val, 0 as tbl FROM AIRWork..TableA
UNION ALL SELECT idx, val, 1 as tbl FROM AIRWork..TableB
)
, CombinedRows As
(
SELECT *,
ROW_NUMBER() OVER(ORDER BY tbl, idx)-1 As k,
COUNT(*) OVER(PARTITION BY 1) - 1 As n
FROM AllRows
)
SELECT ABDest.k As idx, SUM(A.val * B.val) As val
FROM CombinedRows AS ABDest
JOIN CombinedRows AS AB ON AB.k <= ABDest.k
LEFT JOIN AIRWork..TableA As A ON A.idx = AB.k
LEFT JOIN AIRWork..TableB As B ON B.idx = ABDest.k - AB.k
WHERE ABDest.k < ABDest.n
GROUP BY ABDest.k
ORDER BY ABDest.k
GO
仅供参考,我不建议使用整个 table 来存储单个向量。最好将所有向量存储在同一个 table 中并使用名称或 ID 键列来分隔它们。