powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / select в updete вставить rownum
24 сообщений из 24, страница 1 из 1
select в updete вставить rownum
    #39593692
iv_roman_vl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Коллеги, добрый день!

У меня есть такой набор данных, например:
Код: plsql
1.
select a from t where id in (25,26,27) order by id asc;



Результат а, например:
3
7
11

Мне нужно сделать update поля "а" по rownum(т.е. значения поля "а" стали по порядку):
1
2
3

Такой вариант не прокатывает:
Код: plsql
1.
update (select rownum, a from t where id in (25,26,27) order by id asc) set a = rownum;



Помогите, плиз!
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39593694
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iv_roman_vlТакой вариант не прокатывает:
Код: plsql
1.
update (select rownum, a from t where id in (25,26,27) order by id asc) set a = rownum;

RTFM MERGE
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39593696
Dshedoo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
5.
6.
MERGE INTO t
USING (select rownum as x, id from t where id in (25,26,27) order by id asc) z
ON (t.id = z.id)
WHEN MATCHED 
THEN UPDATE 
 SET t.a = z.x
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39593697
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iv_roman_vl
Код: plsql
1.
update (select rownum, a from t where id in (25,26,27) order by id asc) set a = rownum;

rownum формируется до сортировки.
Для приведенного случая проще декодить id, чем городить подзапросы.
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39593699
Dshedoo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dshedoo,

Код: plsql
1.
USING (select row_number() OVER(order by id asc) as x, id from t where id in (25,26,27)) z
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39593703
iv_roman_vl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dshedoo,

Спасибо!!! Работает!!!
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39593767
iv_roman_vl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем спасибо за участие!
Применил вышеуказанные способы и все работает!
Но немного не нравится лаконничность решения.

Задача звучит так:
Книги лежат на полках. У каждой книги на полке есть свое место(номер места).
Книги могут перемещать с полки на полку, либо в начало полки либо в конец.
При перемещении книг в начало полки, номер места перемещаемых книг начинается с 1. Номер места уже имеющихся книг на полке начинается с количества добавленных книг на полку. При этом номера книг с полки откуда переместили, пересчитывается с 1.
При перемещении книг в конец полки, номера книг имеющихся на полке остается прежним, а номера книг перемещаемых на полку начинается с количества книг присутствующих на полке. При этом номера книг с полки откуда переместили, пересчитывается с 1.

Например:
Код: sql
1.
2.
3.
4.
5.
6.
7.
IdКниги| НомерПолки | НомерКнигиНаПолке
1              1                    1
2              1                    2
3              1                    3
4              2                    1
5              2                    2
6              2                    3



При перемещении книг 4,5 с полки 2 на полку 1 в начало полки :
Код: sql
1.
2.
3.
4.
5.
6.
7.
IdКниги| НомерПолки | НомерКнигиНаПолке
1              1                    3
2              1                    4
3              1                    5
4              1                    1
5              1                    2
6              2                    1



При перемещении книг 4,5 с полки 2 на полку 1 в конец полки :
Код: sql
1.
2.
3.
4.
5.
6.
7.
IdКниги| НомерПолки | НомерКнигиНаПолке
1              1                    1
2              1                    2
3              1                    3
4              1                    4
5              1                    5
6              2                    1



Я реализовал это так, начну
Код: plsql
1.
с перемещения книг в конец полки

:
Вначале нахожу количество книг на той полке на которую хочу переместить
Код: plsql
1.
select count(id) into count from Книги where Полка = 1;


Затем, перемещаю книги на полку:
Код: plsql
1.
2.
3.
4.
5.
6.
MERGE INTO Книги
USING (select rownum as x, id from Книги where IDКниги in (4,5) order by id asc) z
ON (Книги.IDКниги = z.id)
WHEN MATCHED 
THEN UPDATE 
 SET Книги.НомерКнигиНаПолке = z.x + count, Книги.НомерПолки = 1;


Локаничность тут меня устраивает.

А теперь,
Код: plsql
1.
с перемещения книг в начало полки

:
Перенумеровываю места книг на полке откуда забираем книги:
Код: plsql
1.
2.
3.
4.
5.
6.
MERGE INTO Книги
USING (select rownum as x, id from Книги where Полка = 2 and IDКниги not in (4,5) order by id asc) z
ON (Книги.IDКниги = z.IDКниги)
WHEN MATCHED 
THEN UPDATE 
 SET Книги.НомерКнигиНаПолке = z.x



Далее, нахожу количество перемещаемых книг:
Код: plsql
1.
select count(id) into count from Книги where id in (4,5);



Далее, Перенумеровываю места книг на полке на которую хочу поставить книги начиная с количества перемещаемых книг:
Код: plsql
1.
2.
3.
4.
5.
6.
MERGE INTO Книги
USING (select rownum as x, id from Книги where Полка = 1 order by id asc) z
ON (Книги.IDКниги = z.IDКниги)
WHEN MATCHED 
THEN UPDATE 
 SET Книги.НомерКнигиНаПолке = z.x + count;



И в конце, перемещаем книги на полку 1:
Код: plsql
1.
2.
3.
4.
5.
6.
MERGE INTO Книги
USING (select rownum as x, id from Книги where id in (4,5) order by id asc) z
ON (Книги.IDКниги = z.IDКниги)
WHEN MATCHED 
THEN UPDATE 
 SET Книги.НомерКнигиНаПолке = z.x, Книги.НомерПолки = 1;




Меня не устраивает локанничность при перемещении в начало полки.
Можно ли как то это записать одним запросом?
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39593775
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iv_roman_vlУ каждой книги на полке есть свое место(номер места).rownum тут не к месту.
Поставить в конец - номер=max+1.
Вытащить - номер=номер-1 для номеров с убранного.
Вставить номер=номер+1 для номеров с вставленного.
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39593826
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iv_roman_vl,

1. не стоит использовать названия переменных такие же как и имена команд, и читать сложно, и проблемы могут возникнуть (into count)
2. не нашел перерасчет полки с которой сняли книги для "вставки в начало" ... если полка останется не сортированной на нее книги вернуть будет сложно
3. Для вставки в начало, я бы вставил записи с НомерКнигиНаПолке = 0 и прогнал один раз перенумерацию с сортировкой order by НомерКнигиНаПолке, id
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39593846
Dshedoo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В процедуру надо передавать ID книг и их новые полки (new_polka) и места (new_mesto).
1) В курсоре выбираем книгу.
2) Запихиваем в old_polka и old_mesto текущее положение книги.
3) Апдейтим все книги на new_polke, у которых mesto >= new_mesto. set mesto = mesto+1
4) Апдейтим все книги на old_polke, у которых mesto > old_mesto. set mesto = mesto - 1.
5) Апдейтим книгу set mesto = new_mesto, polka = new_polka
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39593851
Dshedoo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DshedooВ процедуру надо передавать ID книг и их новые полки (new_polka) и места (new_mesto).
1) В курсоре выбираем книгу.
2) Запихиваем в old_polka и old_mesto текущее положение книги.
3) Апдейтим все книги на new_polke, у которых mesto >= new_mesto. set mesto = mesto+1
4) Апдейтим все книги на old_polke, у которых mesto > old_mesto. set mesto = mesto - 1.
5) Апдейтим книгу set mesto = new_mesto, polka = new_polka
Выполнять пункты в такой последовательности: 1 - 2 - 3 - 5 - 4
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39593908
iv_roman_vl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DshedooВ процедуру надо передавать ID книг и их новые полки (new_polka) и места (new_mesto).
1) В курсоре выбираем книгу.
2) Запихиваем в old_polka и old_mesto текущее положение книги.
3) Апдейтим все книги на new_polke, у которых mesto >= new_mesto. set mesto = mesto+1
4) Апдейтим все книги на old_polke, у которых mesto > old_mesto. set mesto = mesto - 1.
5) Апдейтим книгу set mesto = new_mesto, polka = new_polka

Я так понимаю, что если у нас перемещаются три книги, то действия 2,3,4,5 будут повторятся по три раза.
Этот вариант хорошо подходит если у нас книга может, например из центра полки переместится в другой центр полки.

У меня такого случая быть не может.
У меня книги строго, либо в конец либо в начало. А старая полка в порядке очередности просто пересчитывается. То есть книги на старой полке просто "сдвинули" друг к другу.

И предложенный вариант будет избыточный, так как надо будет пункты 2,3,4,5 повторять для каждой книги.

Все равно спасибо за участие.
Я понял, что мой метод имеет место быть.

Просто меня интересовало, могу ли я два запроса(1-й пересчет от количества перемещаемых книг, 2 - пересчет перемещаемых книг) при перемещении в голову обьеденить в один. Видимо нет. Но все равно всем спасибо.

PS: про имя into count знаю. Спасибо!
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39593943
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iv_roman_vlПросто меня интересовало, могу ли я два запроса(1-й пересчет от количества перемещаемых книг, 2 - пересчет перемещаемых книг) при перемещении в голову обьеденить в один. Видимо нет.

Ну от чего же сразу нет.

Можно написать 1 мердж который основан на сортировке НомерКнигиНаПолке а потом ID по передаваемому значению НомерПолки.

А вставка будет апдейтить НомерПолки на нужную, в начало меняет НомерКнигиНаПолке = 0 для вставляемых книг
в конец меняет НомерКнигиНаПолке переводит в null

После запускаем наш единственный мердж который и пересчитает НомерКнигиНаПолке для старой а потом и для новой полки.
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39593946
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iv_roman_vl,

перемещения в "однопользовательском" режиме?


ps
Вы хотите одним merge убрать книги из полки и положить на другую с перенумерациями?
или оператора два - один знимает книги с полки, другой кладет с перенумерациями?
.....
stax
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39594015
iv_roman_vl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Staxiv_roman_vl,

перемещения в "однопользовательском" режиме?


ps
Вы хотите одним merge убрать книги из полки и положить на другую с перенумерациями?
или оператора два - один знимает книги с полки, другой кладет с перенумерациями?
.....
stax

Да, в однопользовательском.
Да, одним merge.
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39594048
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iv_roman_vl,

книги снимаются с одной полки, или могут сниматся сразу из нескольких?
все снятые книги ставятся на одну конкретную полку?

.....
stax
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39594063
iv_roman_vl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Staxiv_roman_vl,

книги снимаются с одной полки, или могут сниматся сразу из нескольких?
все снятые книги ставятся на одну конкретную полку?

.....
stax

За одну операцию(одного нажатии на кнопку переместить)
Книги снимаются только с одной полки. И ставятся только на одну полку(строго либо в начало полки, либо в конец).

И вопрос в том можно ли сделать перенос книг с одной полки на другую, с соответствующим пересчетом на обеих полках,
при вставке в начало полки,
одним запросом.
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39594079
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iv_roman_vl,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
/*drop table books;
create table books (id number(10), rack number(10), numOfRack number(10));
insert into books (id, rack, numOfRack) values (1,1,1);
insert into books (id, rack, numOfRack) values (2,1,2);
insert into books (id, rack, numOfRack) values (3,1,3);
insert into books (id, rack, numOfRack) values (4,2,1);
insert into books (id, rack, numOfRack) values (5,2,2);
insert into books (id, rack, numOfRack) values (6,2,3);
*/

select row_number() over (partition by case when id in (1,2) then 2/*new rack*/ else rack end
                          order by 
                          case when id in (1,2) then 2/*new rack*/ else rack end, 
                          case when id in (1,2) then decode(2/*1 - at first*/,1,0) else numOfRack end,
                          id) new_numOfRack, 
                          id, case when id in (1,2) then 2/*new rack*/ else rack end new_rack
                          
from books
--where rack in (1,2)

order by new_numOfRack
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39594087
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это я перевожу книги 1 и 2 с полки 1 на полку 2 перерасчитывая две полки (ну их всего две )


где:
Код: plsql
1.
decode(2/*1 - at first*/,1,0)

- 1 - с начала, 2-ка например с конца
Код: plsql
1.
2/*new rack*/

- полка на которую перенесли
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39594107
Dshedoo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iv_roman_vlStaxiv_roman_vl,

книги снимаются с одной полки, или могут сниматся сразу из нескольких?
все снятые книги ставятся на одну конкретную полку?

.....
stax

За одну операцию(одного нажатии на кнопку переместить)
Книги снимаются только с одной полки. И ставятся только на одну полку(строго либо в начало полки, либо в конец).

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

Так вот "одной кнопкой" ты можешь вызывать процедуру, которая и будет делать всё, что я описал ранее.
Правильнее реализовывать не тот подход, который решает конкретную задачу, а тот, который будет универсален, и будет, в том числе, решать конкретную задачу.
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39594120
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iv_roman_vl,

влоб
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
SQL> select * from t order by p,n;

        ID          P          N
---------- ---------- ----------
         1          1          1
         2          1          2
         3          1          3
         4          2          1
         5          2          2
         6          2          3
         7          2          4

7 rows selected.

SQL> print :t_in

      T_IN
----------
         1

SQL> MERGE INTO t
  2  USING (
  3  select
  4    k.*
  5   ,row_number() over (partition by p order by srt,n) rn
  6  from
  7   (select id,p,n,1 srt from t where p=:t_in --старые книги
  8    union all
  9    select id,:t_in,n,0 srt from t where id in (4,5) -- добавленные (0- в начало  2- в конец)
 10    union all
 11    select id,p,n,1 srt from t where id not in (4,5)
 12                        and p=(select min(p) from t where id in (4,5)) -- без снятих
 13   ) k
 14  ) z
 15  ON (t.ID = z.ID)
 16  WHEN MATCHED
 17  THEN UPDATE
 18   SET t.p=z.p, n=z.rn
 19  /

7 rows merged.

SQL> select * from t order by p,n;

        ID          P          N
---------- ---------- ----------
         4          1          1
         5          1          2
         1          1          3
         2          1          4
         3          1          5
         6          2          1
         7          2          2

7 rows selected.

SQL> rollback;

Rollback complete.

SQL> ed
Wrote file afiedt.buf

  1  MERGE INTO t
  2  USING (
  3  select
  4    k.*
  5   ,row_number() over (partition by p order by srt,n) rn
  6  from
  7   (select id,p,n,1 srt from t where p=:t_in --старые книги
  8    union all
  9    select id,:t_in,n,2 srt from t where id in (4,5) -- добавленные (0- в начало  2- в конец)
 10    union all
 11    select id,p,n,1 srt from t where id not in (4,5)
 12                        and p=(select min(p) from t where id in (4,5)) -- без снятих
 13   ) k
 14  ) z
 15  ON (t.ID = z.ID)
 16  WHEN MATCHED
 17  THEN UPDATE
 18*  SET t.p=z.p, n=z.rn
SQL> /

7 rows merged.

SQL> select * from t order by p,n;

        ID          P          N
---------- ---------- ----------
         1          1          1
         2          1          2
         3          1          3
         4          1          4
         5          1          5
         6          2          1
         7          2          2

7 rows selected.

SQL> rollback;

Rollback complete.

SQL>



....
stax
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39594167
iv_roman_vl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax,

Спасибо, это именно то что нужно!!!!!!!!!!!!!!!!!!

Скрипт ОГОНЬ!!!

ОГРОМНЫЙ РЕСПЕКТ!!!

чувствую как мой скил прокачался!!!!
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39594183
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iv_roman_vl,

можно сделать и оптимальнее (без/меньше union all), условие выборки будет запутанее

делал влоб, чтоб понятнее было

ps
снятие книг с нескольких полок одновременно
p in (select p from t where id in (4,5))


.....
stax
...
Рейтинг: 0 / 0
select в updete вставить rownum
    #39594592
iv_roman_vl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax,

Да, спасибо! Принцип понял.
Пока с нескольких полок не требуется.
Но возьму на вооружение.
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / select в updete вставить rownum
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]