Реализация итеративного подхода к хранимым процедурам в стиле SQL - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь реализовать свертку между двумя векторами v1 и v2. В рамках этого я написал хранимую процедуру с итеративным подходом, используя циклы while. Вот код ниже, как показано ниже. Я не могу придумать, как это сделать с помощью SQL, поскольку хранимая процедура неэффективна с точки зрения производительности. Может кто-нибудь поделиться своими мыслями по этому поводу? Любые вклады будут оценены.

Идея написания хранимой процедуры:

https://software.intel.com/en-us/ipp-dev-reference-convolve

enter image description here

Схема таблицы и пример входных данных:

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

1 Ответ

0 голосов
/ 26 апреля 2018

Эта процедура должна сделать это:

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

К вашему сведению, я бы не рекомендовал использовать целую таблицу для хранения одного вектора. Вам было бы гораздо лучше сохранить все свои векторы в одной таблице и использовать столбец имени или ключа ключа для их разделения.

...