Найти последовательные строки из n с помощью SQLite

3

У меня есть эта таблица со значениями:

val  
1
2
3
7
8
9

В таблице также есть столбец идентификатора, не относящийся прямо сейчас.

Я хочу вставить одно значение, но в правиле не может быть никаких повторяющихся значений. Скажем, я вставляю новый 2, ток 2 должен стать 3 и т.д. До значения 3, которое превратится в 4. В этом случае значения 7, 8 и 9 не нужно "перемещать".

Я работаю с SQLite. Часть вставки или обновления может быть выполнена в отдельном запросе после того, как желаемый новый держатель значений будет перемещен.

До сих пор я делал это с помощью

//being n my new value.
UPDATE values SET val = val+1 WHERE val >= n 

Но это также изменит 7,8 и 9, которые не нужно изменять.

Любые мысли о том, как решить эту часть проблемы? Ограничение обновления только последовательными значениями?

Лучше всего сделать всю вставку/обновление в одном запросе. Также будет очень признателен.

  • 1
    Вы также можете изменить нумерацию значений при удалении отдельных строк, таких как UPDATE values SET val = val-1 WHERE val >= n . Таким образом, вы всегда будете иметь последовательные числа и снова сможете использовать UPDATE values SET val = val+1 WHERE val >= n . Не оптимально, но работает.
  • 0
    Спасибо за идею, но источником непоследовательности является пользователь. Эти значения используются в качестве приоритетов, и пользователь может переназначить приоритет задачи и назначить ей случайный приоритет в диапазоне от 1 до 20.
Показать ещё 1 комментарий
Теги:

1 ответ

2
Лучший ответ

Решение №1 с LEFT JOIN:

http://sqlfiddle.com/#!5/7eeea/12

UPDATE t
SET val = val+1
WHERE val >= 2
  AND val <= (
    SELECT MIN(t1.val)
    FROM      t AS t1
    LEFT JOIN t AS t2 ON t1.val+1 = t2.val
    WHERE t1.val >= 2
      AND t2.val IS NULL
  );

Решение №2 с NOT EXISTS:

http://sqlfiddle.com/#!5/7eeea/17

UPDATE t
SET val = val+1
WHERE val >= 2
  AND val <= (
        SELECT MIN(t1.val)
        FROM  t AS t1
        WHERE t1.val >= 2
          AND NOT EXISTS (SELECT 1 FROM t AS t2 WHERE t1.val+1 = t2.val)
  );
  • 0
    Отличный ответ, очень хорошо исследованный, и я не знал sqlfiddle. Я скажу, что вам нужно привести любое значение к целому числу CAST (val AS INTEGER) в частях сравнения, чтобы оно работало, по крайней мере, в моем случае, так как я установил для него сходство STRING. Ваши решения работают отлично, я лично выбираю второе, которое я понял, как оно работает.
  • 1
    Небольшая иллюстрация для первого варианта: sqlfiddle.com/#!5/7eeea/22 :)
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню