Программирование регрессии с использованием plsql для получения идеального соответствия - PullRequest
0 голосов
/ 18 октября 2019

Я работаю над функцией, чтобы получить идеальное соответствие из набора чисел (минимальное значение равно 1, а максимальное значение равно 25).

Я дал ниже DDL для создания таблицы, а также операторов вставки и кода, над которым я сейчас работаю, с проблемами производительности.

Запустите приведенный ниже код.

Это будет выполнено через 2 минуты, если количество записей равно 20.

Общее количество записей, которые я здесь приведу, составляет 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;

1 Ответ

0 голосов
/ 21 октября 2019

Мы должны полностью завершить вызов функции после того, как совпадение найдено. Я создал глобальную переменную и проверил, найдено ли совпадение, затем полностью вернусь из вызовов функций. Таким образом, программа завершается быстро.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...