我需要匹配两个表中的行。匹配完成后,我会删除匹配的行并继续匹配后续匹配。
我的存储过程一直工作到某个匹配,然后迭代同一匹配,直到我的 while 循环达到其行限制。我设置此行限制是因为 SP 之前无限循环。
我不确定我做错了什么。
DELIMITER //
CREATE PROCEDURE MatchTransactions()
BEGIN
-- Declare variables at the beginning
DECLARE rows_deleted INT DEFAULT 1;
DECLARE min_rows INT;
-- Create temporary tables
CREATE TEMPORARY TABLE TempA AS SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS row_num FROM SA_A;
CREATE TEMPORARY TABLE TempB AS SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS row_num FROM SA_B;
-- Get the minimum number of rows between the two tables
SELECT LEAST((SELECT COUNT(*) FROM TempA), (SELECT COUNT(*) FROM TempB)) INTO min_rows;
-- Create a table to store the matches
CREATE TABLE Matches (A_row INT, B_row INT, A_ID INT, B_ID INT);
-- Loop until no more matches are found or the number of iterations exceeds the minimum number of rows
WHILE rows_deleted > 0 AND (SELECT COUNT(*) FROM Matches) < min_rows DO
-- Reset rows_deleted
SET rows_deleted = 0;
-- Start a new transaction
START TRANSACTION;
-- Find a match
SELECT A.row_num, B.row_num, A.A_ID, B.B_ID INTO @match_A, @match_B, @A_id, @B_id
FROM TempA AS A
INNER JOIN TempB AS B
ON A.ENTRY_DATE = B.TRANSACTION_DATE
AND A.TRANSACTION_AMOUNT = B.TRANSACTION_AMOUNT
AND A.CREDIT_DEBIT = B.CREDIT_DEBIT
AND A.ACCOUNT = B.PRIMARY_ACCOUNT
AND ABS(TIMEDIFF(A.TIME, B.TIME)) <= '00:00:15'
LIMIT 1;
-- If a match was found, delete it from both tables and add it to the Matches table
IF @A_id IS NOT NULL AND @B_id IS NOT NULL THEN
DELETE FROM TempA WHERE A_ID = @A_id;
DELETE FROM TempB WHERE B_ID = @B_id;
INSERT INTO Matches(A_row, B_row, A_ID, B_ID) VALUES (@match_A, @match_B, @A_id, @B_id);
-- Get the number of rows deleted in this iteration
SET rows_deleted = ROW_COUNT();
END IF;
-- Commit the transaction
COMMIT;
END WHILE;
-- Select the matches
SELECT * FROM Matches;
-- Drop the temporary tables and the Matches table
DROP TEMPORARY TABLE IF EXISTS TempA;
DROP TEMPORARY TABLE IF EXISTS TempB;
DROP TABLE IF EXISTS Matches;
END//
DELIMITER ;
如前所述,我在 WHILE 循环上添加了 min_rows 约束以强制其终止,无论如何,我的 Matches 表中的理论最大行数最多应该等于 min_rows。
找到匹配项后,将其从两个源表中删除,然后将其添加到
Matches
表中。没错,但是当有些行无法匹配时会发生什么,因此 while 条件 (SELECT COUNT(*) FROM Matches) < min_rows
始终满足?
如果发生这种情况,
Matches
表中的行数将永远不会至少等于变量min_rows
- 因此它会无限运行。
当未找到匹配项时,也许您应该减少变量的值
min_rows
?
getting stuck on the same row
的原因完美证实了我所说的。存储过程找不到该行的匹配项,因此它继续运行,因为 (SELECT COUNT(*) FROM Matches) < min_rows
的结果是 TRUE
。