Измените порядок всех строк в таблице SQLite с помощью настраиваемого столбца order_index - PullRequest
0 голосов
/ 05 мая 2020

У меня есть таблица SQLite persons:

+-----------+----------+-------------+
| id        | name     | order_index |
+-----------+----------+-------------+
| (primary) |          | (unique)    |
+-----------+----------+-------------+
| 0         | Paul     | 1           |
+-----------+----------+-------------+
| 1         | Sammy    | 2           |
+-----------+----------+-------------+
| 2         | Caren    | 0           |
+-----------+----------+-------------+
| 3         | Muhammed | 3           |
+-----------+----------+-------------+

Мне нужно отслеживать порядок, используя настраиваемый столбец order_index. Столбец order_index должен начинаться с 0.

Допустим, я хочу переместить Muhammed в позицию 1. Это требует, чтобы я также обновил order_index из Sammy и Paul. order_index из Caren не нужно изменять, поскольку 1 > 0.

Можно ли добиться этого с помощью SQLite?

Ответы [ 3 ]

0 голосов
/ 05 мая 2020

Это сложное требование, поскольку оно включает в себя несколько обновлений, которые зависят друг от друга, и порядок этих обновлений не гарантируется.

Сначала обновите все остальные строки, которые необходимо обновить, кроме строки человека, которого вы хотите переместить:

with cte as (
  select name, order_index current_index, ? new_index
  from persons 
  where name = 'Muhammed'
) 
update persons
set order_index = order_index + 
  case 
    when (select current_index from cte) > (select new_index from cte) then 1 
    else -1 
  end
where name <> (select name from cte) 
  and order_index between 
    min((select current_index from cte), (select new_index from cte))
    and
    max((select current_index from cte), (select new_index from cte));

Затем обновите строку человека, которого вы хотите переместить:

update persons
set order_index = ?                                        
where name = 'Muhammed'; 

Замените заполнители ? в обоих запросах на новую позицию. См. Демонстрацию .

0 голосов
/ 06 мая 2020

Я создал решение ( демонстрация ) на основе предложений Тима и forpas :

# Move person from index 4 to index 2:

# Update target index.
update persons
set order_index = NULL                                        
where order_index = 4; # FROM

# Update indexes >= TO.
update persons
set order_index = order_index + 1                                        
where order_index >= 2; # TO

# Update indexes > FROM.
update persons
set order_index = order_index - 1                                        
where order_index > 4; # FROM

# Update target.
update persons
set order_index = 2 # TO                                     
where order_index IS NULL;

# Show results.
select id, name, order_index from persons ORDER BY order_index;

Я думаю, что это решение несколько проще gr asp, чем предложение forpas. Однако есть ли причины использовать вместо этого предложение forpas?

0 голосов
/ 05 мая 2020

Это не полный ответ, потому что может потребоваться изменить всю вашу модель данных, но я бы обработал это конкретное c требование с помощью следующего запроса:

UPDATE persons
SET order_index = (SELECT MIN(order_index) FROM persons) - 1
WHERE name = 'Muhammed';

То есть просто удар Позиция Мухаммеда на единицу минус текущий наивысший приоритет. Тогда ваша бизнес-логика c должна всегда обслуживать человека с наименьшим индексом заказа (который может даже go отрицательный).

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