Home > database >  How insert one item between sorted items SQL
How insert one item between sorted items SQL

Time:05-25

I have a table like this :

id     name  family  order
861    a     a       1
5241   b     b       2
15     c     c       3
251    d     d       4
.
.
.
541    e     e       9001
41     f     f       9002
8161   g     g       9003

When I want get my data I use this query :

SELECT * FROM users ORDER BY order ASC;

But also I need insert one item between two items with id 861 and 5241. So in this way I need change all orders of all rows.

UPDATE users SET order=9004 WHERE order=9003;
UPDATE users SET order=9003 WHERE order=9002;
UPDATE users SET order=9002 WHERE order=9001;
.
.
.
UPDATE users SET order=4 WHERE order=3;
UPDATE users SET order=3 WHERE order=2;
INSERT INTO users (name, family, order) VALUES ('z', 'z', 2);

And we know it is very bad idea. Is there a better way?

CodePudding user response:

Something like this:

START TRANSACTION;
UPDATE users SET order_c = order_c 1 where order_c >= 2;
insert into users values(123, 'f', 'f', 2);
COMMIT;

Here is a demo

I think the exact was recommended by @EdmCoff ?

CodePudding user response:

Given

select * from t;
 ------------ ---------- 
| dte        | order_id |
 ------------ ---------- 
| 2018-01-02 |        1 |
| 2018-01-03 |        2 |
| 2018-01-04 |        3 |
| 2018-01-05 |        4 |
| 2018-01-06 |        5 |
| 2018-01-07 |        6 |
| 2018-01-08 |        7 |
| 2018-01-09 |        8 |
| 2018-01-10 |        9 |
| 2018-01-11 |       10 |
 ------------ ---------- 

If you want to code and forget consider

drop trigger if exists t;
delimiter $$

create trigger t after insert on t
for each row 
begin
     insert into t1 values (new.dte,new.order_id,null,0);
end $$
delimiter ; 

create table t1 like t;

alter table t1
    add column AI_order_id int auto_increment primary key,
    add column new_order_id int;
alter table t1
    add unique key (order_id,AI_order_id);

truncate table t1;

insert into t1  select dte,order_id, null,0 from t; #bulk load

#select * from t1;

insert into t values (date('2023-05-01'),2),(date('2024-05-01'),2),(date('2024-05-01'),10),(date('2024-05-01'),1);

update t1 join
    (select order_id,AI_order_id, row_number() over(order by order_id,AI_order_id desc) rn from t1) s
    on t1.order_id = s.order_id and t1.AI_order_id = s.AI_order_id
    set new_order_id = s.rn
    where 1 = 1;

update t join t1 on t1.order_id = t.order_id and t1.dte = t.dte
set    t.order_id = t1.new_order_id
where 1 = 1;

select * from t1 order by order_id,new_order_id;

 ------------ ---------- ------------- -------------- 
| dte        | order_id | AI_order_id | new_order_id |
 ------------ ---------- ------------- -------------- 
| 2024-05-01 |        1 |          19 |            1 |
| 2018-01-02 |        1 |           1 |            2 |
| 2024-05-01 |        2 |          17 |            3 |
| 2023-05-01 |        2 |          16 |            4 |
| 2018-01-03 |        2 |           2 |            5 |
| 2018-01-04 |        3 |           3 |            6 |
| 2018-01-05 |        4 |           4 |            7 |
| 2018-01-06 |        5 |           5 |            8 |
| 2018-01-07 |        6 |           6 |            9 |
| 2018-01-08 |        7 |           7 |           10 |
| 2018-01-09 |        8 |           8 |           11 |
| 2018-01-10 |        9 |           9 |           12 |
| 2024-05-01 |       10 |          18 |           13 |
| 2018-01-11 |       10 |          10 |           14 |
 ------------ ---------- ------------- -------------- 
14 rows in set (0.001 sec)

select * from t  order by order_id;

 ------------ ---------- 
| dte        | order_id |
 ------------ ---------- 
| 2024-05-01 |        1 |
| 2018-01-02 |        2 |
| 2024-05-01 |        3 |
| 2023-05-01 |        4 |
| 2018-01-03 |        5 |
| 2018-01-04 |        6 |
| 2018-01-05 |        7 |
| 2018-01-06 |        8 |
| 2018-01-07 |        9 |
| 2018-01-08 |       10 |
| 2018-01-09 |       11 |
| 2018-01-10 |       12 |
| 2024-05-01 |       13 |
| 2018-01-11 |       14 |
 ------------ ---------- 
14 rows in set (0.001 sec)
  • Related