Как перебирать числа в SQL с разными приращениями - PullRequest
4 голосов
/ 01 мая 2019

Я пытаюсь перебрать числа в SQL, которые имеют начальное значение 10 и увеличиваются на значение от 7 до 59. В языке на основе C это было бы невероятно просто, но у меня возникли проблемы с реализациейэто в Oracle SQL.

Я пытался использовать цикл for и умножать каждую итерацию на 7, но я не знаю, как запустить и завершить цикл при определенных значениях.

DECLARE
incrementor PLS_INTEGER := 7;
BEGIN
    FOR i IN 10..59 LOOP
        dbms_output.put_line('x = '|| i * incrementor);
    END loop;
END;

Желаемый результат будет:

x = 10
x = 17
x = 24
x = 31
x = 38
x = 45
x = 52
x = 59

Но вместо этого я получаю:

x = 70
x = 77
x = 84
x = 91

и так далее ...

Любые идеи о том, как ябудет делать это?Заранее спасибо за помощь!

1 Ответ

7 голосов
/ 01 мая 2019

for-loop не позволяет вам указывать приращение, к сожалению, только количество итераций.

Ваш код перебирает каждое целое число от 10 до 59, поэтомуВы повторяете цикл 50 раз, причем i устанавливается на 10, 11, ... 58, 59;а затем для каждой итерации вы умножаете это значение i на 7 - следовательно, вы получаете 50 результатов со значениями 70, 77, ... 406, 413.

Чтобы получить нужный результат, вы можете вычислитьфактическое количество необходимых итераций, а затем добавьте начальное значение диапазона к результату умножения внутри цикла:

DECLARE
    incrementor PLS_INTEGER := 7;
BEGIN
    FOR i IN 0..floor((59 - 10)/incrementor) LOOP
        dbms_output.put_line('x = '|| (10 + i * incrementor));
    END loop;
END;
/

x = 10
x = 17
x = 24
x = 31
x = 38
x = 45
x = 52
x = 59


PL/SQL procedure successfully completed.

Вы можете использовать больше переменных, чтобы избежать повторения, конечно:

DECLARE
    incrementor PLS_INTEGER := 7;
    low_value PLS_INTEGER := 10;
    high_value PLS_INTEGER := 59;
BEGIN
    FOR i IN 0..floor((high_value - low_value)/incrementor) LOOP
        dbms_output.put_line('x = '|| (low_value + i * incrementor));
    END loop;
END;
/

Вы пометили вопрос для PL / SQL, и именно это вы использовали в своей попытке;но как ваш вопрос относится к SQL;Вы можете сделать это в простом SQL с помощью иерархического запроса:

select 10 + (7 * (level - 1)) as result
from dual
connect by level <= floor((59 - 10)/7) + 1;

    RESULT
----------
        10
        17
        24
        31
        38
        45
        52
        59

8 rows selected. 

или с помощью рекурсивного факторинга подзапроса:

with rcte (result) as (
  select 10
  from dual
  union all
  select result + 7
  from rcte
  where result < 59
)
select result
from rcte;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...