Как сбросить нумерацию, если между числами есть пробелы и они расположены в случайном порядке? - PullRequest
0 голосов
/ 14 июля 2020

У меня товары отображаются в двух HTML таблицах. Их порядок пронумерован от 1 до бесконечности и является непрерывным в обеих таблицах. Например, если номер последнего продукта в первой таблице равен 5, то номер первого продукта во второй таблице будет 6, et c.

Когда продукт из второй таблицы перемещается к первой таблице мне нужно вручную изменить номера заказов в базе данных. Таким образом, если продукт 8 перемещается в первую таблицу, там он находится под номером 6 (последний продукт). Это я сделал. Теперь первая таблица имеет нумерацию ... 4 - 5 - 6, а вторая таблица: 6 - 7 - 9 - 10 - et c., Но должна быть установлена ​​на 7 - 8 - 9 - 10, et c.

Информация о нумерации обеих таблиц хранится в одной таблице базы данных. (У каждого продукта есть параметр, указывающий, входит ли он в таблицу 1 или 2, но чтобы добраться до него, мне нужно выполнить внутреннее соединение.)

Как правильно сбросить нумерацию второй таблицы с помощью PL? / SQL?

У меня есть что-то вроде

select order_number
into v_old_order_number
from products
where product_id = moved_product_id; --find product's current order number

select product_id bulk collect into v_first_table_product_ids
from products p 
inner join table_with_parameter t
on p.product_id = t.product_id
and t.parameter = 1; --find all first table product ids

select max(order_number) + 1
into v_new_order_number
from products
where product_id member of v_first_table_product_ids; --find max order value of first table
                                                      --products, put in variable and add 1

update products
set order_number = v_new_order_number
where product_id = moved_product_id; --change our product's order number to new order number

update products
set order_number = order_number + 1
where order_number => v_new_order_number
and order_number <= v_oold_order_number
and product_id != moved_product_id; --change all numbers greater than new_order_no 
                                    --(except if it has the moved product's id) 
                                    --and smaller than old_order_no.

Я уверен, что это можно сделать лучше.

1 Ответ

0 голосов
/ 15 июля 2020

В будущем, пожалуйста, включите небольшой пример (например, тот, который я построил ниже), который люди могут использовать, чтобы помочь вам. Это поможет прояснить ваш вопрос и гарантирует, что время, которое люди добровольно участвуют в SO, потрачено не зря.

Я думаю, вы можете делать все, что хотите, с помощью MERGE. Я использую elastic_rank () для расчета заказа на основе идентификатора таблицы и существующего заказа и перенумерации каждого продукта. Затем MERGE обновит только те строки, которые необходимо изменить.

CREATE TABLE products (
    table_id NUMBER, 
    product_id NUMBER,
    order_id NUMBER);
  
ALTER TABLE products  
ADD CONSTRAINT products_pk
PRIMARY KEY (product_id)
USING INDEX;

BEGIN
  INSERT INTO products VALUES (1, 1, 1);
  INSERT INTO products VALUES (1, 2, 2);
  INSERT INTO products VALUES (1, 3, 3);
  INSERT INTO products VALUES (1, 4, 4);
  INSERT INTO products VALUES (1, 5, 5);

  INSERT INTO products VALUES (2, 6, 6);
  INSERT INTO products VALUES (2, 7, 7);
  INSERT INTO products VALUES (2, 8, 8);
  INSERT INTO products VALUES (2, 9, 9);
  INSERT INTO products VALUES (2, 10, 10);

  COMMIT;
END;
/

SELECT *
  FROM products
 ORDER BY table_id,
          order_id;
/*
T P O
1 1 1
1 2 2
1 3 3
1 4 4
1 5 5
2 6 6
2 7 7
2 8 8
2 9 9
2 10  10
*/

UPDATE products 
   SET table_id = 1
 WHERE product_id = 8;
 
SELECT *
  FROM products
 ORDER BY table_id,
          order_id;
/*
T P O
1 1 1
1 2 2
1 3 3
1 4 4
1 5 5 <--
1 8 8 <--
2 6 6
2 7 7 <--
2 9 9 <--
2 10  10
*/

MERGE INTO products p
USING (SELECT product_id,
              dense_rank() over(ORDER BY table_id, order_id) AS order_id
         FROM products) x
ON (p.product_id = x.product_id)
WHEN MATCHED THEN
  UPDATE
     SET p.order_id = x.order_id
   WHERE p.order_id != x.order_id;
-- 4 rows updated

SELECT *
  FROM products
 ORDER BY table_id,
          order_id;
/*
T P O
1 1 1
1 2 2
1 3 3
1 4 4
1 5 5
1 8 6
2 6 7
2 7 8
2 9 9
2 10  10
*/
...