【问题标题】:Find consecutive rows from n with SQLite使用 SQLite 从 n 中查找连续行
【发布时间】:2012-07-15 14:58:28
【问题描述】:

我有这个带有值的表:

val  
1
2
3
7
8
9

该表还有一个 id 列,目前不相关。

我想插入一个值,但规则是不能有任何重复值。假设我插入了一个新的 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,不需要修改。

对如何解决这部分问题有任何想法吗?将更新限制为仅连续值?

在一个查询中进行整个插入/更新的更好方法也将不胜感激。

【问题讨论】:

  • 您也可以在删除像UPDATE values SET val = val-1 WHERE val >= n 这样的单行时重新编号。这样,您将始终拥有连续的数字,并且可以再次使用UPDATE values SET val = val+1 WHERE val >= n。不是最佳的,但可以工作。
  • 感谢您的想法,但不连续性的来源是用户。此值用作优先级,用户可以重新分配任务的优先级,并为其分配一个随机优先级,范围为 1 到 20。
  • 如果val 列有一个实际的UNIQUE 约束,那么您可能需要UPDATE ... ORDER BY,遗憾的是默认情况下它没有编译为SQLite。 sqlite.org/lang_update.html

标签: sql sqlite


【解决方案1】:

LEFT JOIN 的解决方案 #1:

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
  );

NOT EXISTS 的解决方案 #2:

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)
  );

【讨论】:

  • 很好的答案,很好的研究,我不知道 sqlfiddle。我会说你需要在比较部分将任何值转换为整数 CAST(val AS INTEGER) 以使其工作,至少在我的情况下,因为我在那里将亲和力设置为 STRING。您的解决方案完美无缺,我个人选择第二个,这是我理解它的工作原理。
  • 第一个变体的小插图:sqlfiddle.com/#!5/7eeea/22 :)
  • +1 非常感谢!我终于将这个解决方案应用于我过度膨胀的查询 xD 再次感谢。
猜你喜欢
  • 1970-01-01
  • 2015-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-18
  • 2014-07-18
  • 2016-02-05
  • 1970-01-01
相关资源
最近更新 更多