2017-02-07 8 views
1

У меня есть стол с двумя колоннами. В первом столбце X имеются номера от 1 до 10000. Второй столбец Y пуст. Это, как я установить это:Как обновить и разделить значения столбцов?

create table test1 (
    x number, 
    y number 
); 

begin 
    for l in 1..10000 LOOP 
    insert into test1(x) 
    values(l); 
    end loop; 
    commit; 
end; 

Мой первый вопрос: мне нужно использовать оператор обновления для установки значения столбца Y в обратном порядке к тем, в колонке X, то есть от 10000 до 1. Строка с X = 1 должна иметь Y = 10000; строка с X = 2 должна обозначать Y = 9999; и т. д. Как я могу это сделать?

Мой второй вопрос: как я могу выполнить математическую операцию (SQL или PL/SQL) , которая оставит в столбце только те числа, которые можно разделить на 17?

+0

Если текущая цель состоит в том, чтобы узнать, PL/SQL, и использовать это только для практики, так сказать ** ** в вашем чтобы избежать всех ненужных вопросов. Все правильно, что все это должно быть сделано в SQL; единственным значимым исключением является то, что вы делаете это для учебных целей, и сейчас вы изучаете PL/SQL, а не SQL. – mathguy

ответ

3

Для делится на 17, используйте mod()

where mod(x,17) = 0 -- remainder (MOD) when divided by 17 = 0 
+0

спасибо, что вы можете дать мне пример в pl/sql) –

2

Ответ на первый вопрос:

update test1 
set y = 10001 - x 
; 

commit; 
+0

спасибо) Можете ли вы дать мне пример в pl/sql same –

+0

@ Смок Белью - Зачем вам нужен pl/sql, если чистый SQL может сделать работу? – RIKI

+0

для изучения моего друга :) –

1

Вам не нужно PL/SQL или оператор обновления:

INSERT INTO test1 (x, y) 
    SELECT CASE MOD(lvl, 17) 
      WHEN 0 
      THEN lvl * 3 -- Your "math operation" 
      ELSE lvl 
      END, 
     10001 - lvl 
    FROM (SELECT LEVEL AS lvl 
      FROM DUAL 
      CONNECT BY LEVEL <= 10000); 

COMMIT; 

Или:

INSERT INTO test1 (x, y) 
WITH cte (lvl) AS (
    SELECT 1 FROM DUAL 
UNION ALL 
    SELECT lvl + 1 
    FROM cte 
    WHERE lvl < 10000 
) 
SELECT CASE MOD(lvl, 17) 
     WHEN 0 
     THEN lvl * 3 -- Your "math operation" 
     ELSE lvl 
     END, 
     10001 - lvl 
FROM cte; 

Но если вам нужно PL/SQL, то вы можете просто обернуть его в анонимном блоке:

DECLARE 
    upper_bound CONSTANT NUMBER := 10000; 
BEGIN 
    INSERT INTO test1 (x, y) 
    SELECT CASE MOD(lvl, 17) 
      WHEN 0 
      THEN lvl * 3 -- Your "math operation" 
      ELSE lvl 
      END, 
      upper_bound + 1 - lvl 
    FROM (SELECT LEVEL AS lvl 
      FROM DUAL 
      CONNECT BY LEVEL <= upper_bound); 

    COMMIT; 
END; 
/
1

Очень простой SQL-запрос whoich будет достаточно вашу проблему. Надеюсь, поможет.

MERGE INTO TEST1 USING 
(SELECT X,ROW_NUMBER() over(order by 1 ASC) Y FROM TEST1 ORDER BY 1 DESC 
)a ON (TEST1.X =a.X) 
WHEN matched THEN 
    UPDATE SET TEST1.Y = DECODE(MOD(A.Y,17),0,A.Y,NULL); 
1

ОК, если вам это нужно в PL/SQL

begin 
    update test1 
    set y = 10001 - x; 
end; 
/
commit; 
+0

Положите «редактирование» лабиринта и объедините этот ответ со своим предыдущим ответом, а не отправляйте другой ответ. – XING