oracle - 使用 plsql 进行回归编程以获得完美匹配
问题描述
我正在研究一个函数,以从一组数字中获得完美匹配(最小值为 1,最大值为 25)。
我在下面给出了创建表的 DDL 以及插入语句和我目前正在处理的代码,这些代码存在性能问题。
运行以下代码。
如果记录数为 20,这将在 2 分钟内运行。
我这里给出的总记录是 33 条,所以需要很长时间,不确定是否完成。
任何输入都会有很大帮助。
CREATE TABLE xx_perfect_combi_test
(
trx_id NUMBER
,trx_val NUMBER
);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051303, 25);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051304, 25);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051305, 25);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051306, 24);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051307, 24);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051308, 24);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051309, 24);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051310, 23);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051311, 23);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051312, 23);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051313, 22);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051314, 22);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051315, 21);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051316, 21);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051317, 21);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051318, 20);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051319, 20);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051320, 20);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051321, 20);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051322, 18);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051323, 17);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051324, 11);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051325, 9);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051326, 8);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051327, 6);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051328, 6);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051329, 4);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051330, 3);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051331, 1);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051332, 1);
COMMIT;
我的程序:
DECLARE
ln_total_sum NUMBER := 315;
ln_orig_diff NUMBER := ln_total_sum;
ln_curr_diff NUMBER;
lv_trx_ids VARCHAR2 (4000);
lv_trx_ids_buff VARCHAR2 (4000);
lv_dummy_return VARCHAR2 (4000);
FUNCTION perfect_combo (p_curr_sum IN NUMBER
,p_curr_vals IN VARCHAR2
,p_rownumber IN NUMBER)
RETURN VARCHAR2
IS
lv_buf_trx_id VARCHAR2 (4000);
BEGIN
FOR c1 IN (SELECT *
FROM (SELECT stg2.*
,ROW_NUMBER () OVER (ORDER BY stg2.trx_val DESC) AS rownumber1
FROM xx_perfect_combi_test stg2)
WHERE rownumber1 > p_rownumber
ORDER BY trx_val DESC) LOOP
--dbms_output.put_line ('p_curr_sum: ' || p_curr_sum);
--dbms_output.put_line ('p_curr_vals: ' || p_curr_vals);
--dbms_output.put_line ('p_rownumber: ' || p_rownumber);
--dbms_output.put_line ('---------------------------------------------------');
IF ( (p_curr_sum + c1.trx_val) = ln_total_sum)
THEN
lv_buf_trx_id := p_curr_vals;
lv_buf_trx_id := lv_buf_trx_id || c1.trx_id || ';';
lv_trx_ids := lv_buf_trx_id;
RETURN lv_trx_ids;
ELSIF (p_curr_sum + c1.trx_val) > ln_total_sum
THEN
ln_curr_diff := ln_total_sum - p_curr_sum;
IF ln_curr_diff < ln_orig_diff
THEN
ln_orig_diff := ln_curr_diff;
lv_trx_ids_buff := p_curr_vals;
END IF;
CONTINUE;
ELSIF (p_curr_sum + c1.trx_val) < ln_total_sum
THEN
ln_curr_diff := ln_total_sum - (p_curr_sum + c1.trx_val);
lv_buf_trx_id := p_curr_vals;
lv_buf_trx_id := lv_buf_trx_id || c1.trx_id || ';';
IF ln_curr_diff < ln_orig_diff
THEN
ln_orig_diff := ln_curr_diff;
lv_trx_ids_buff := lv_buf_trx_id;
END IF;
lv_dummy_return := perfect_combo ( (p_curr_sum + c1.trx_val), lv_buf_trx_id, c1.rownumber1);
END IF;
END LOOP;
RETURN NULL;
END perfect_combo;
BEGIN
lv_dummy_return := perfect_combo (0, NULL, 0);
DBMS_OUTPUT.put_line ('lv_trx_ids: ' || lv_trx_ids);
DBMS_OUTPUT.put_line ('lv_trx_ids_buff: ' || lv_trx_ids_buff);
END;
解决方案
找到匹配项后,我们必须完全退出函数调用。我创建了一个全局变量并检查是否找到匹配项,然后从函数调用中完全返回。这样程序很快就完成了。
推荐阅读
- vb6 - 在 Tally ERP9 响应 xml 中
- flutter - Flutter - 在 Flutter 导航堆栈中获取 TopView 的名称
- excel - 从 Excel 工作表中删除公式
- c# - 如何获取 IBuffer 的 C# TypeCode?
- html - 使用 HTML 获取双标头时遇到问题
- c# - 覆盖口袋妖怪名称
- java - 我可以使用 getComponents() 而不是保留组件的 ArrayList 吗?
- sql - 如何在 SQL 中获取唯一对,其中该对的任何部分都不存在于其他对中
- swift - 当数组包含日期时,从 Firestore 中删除数组项不起作用
- svg - 为什么文本会出现在浏览器中,但不会出现在图像查看器中?