2017-06-19 75 views
0

我按表格形式在sqlite上按字母順序輸入單詞,它已被編號......假設我想在sylite經理的兩行之間添加一行,也許編號爲2 「aa」和3號是「ac」,如果我想在aa和ac之間添加「ab」,並使ab號碼3和ac號碼4,我該如何輕鬆地做到這一點?如何在sqlite管理器上的兩行之間插入另一行

回答

1

DBFiddle Demo of Update Statement

由於sqlite的不支持Windows的分析功能,這將是有點棘手,實現這一目標。您也可以使用類似的邏輯創建一個before insert觸發器。

假設:

  1. 號碼與任何整數開始,像在這種情況下2並將於1遞增。所以現有數據中沒有丟失序列。

  2. 字母數字排序是適用其中aa < aaa < ab < ac。這由RDBMS根據字符串中每個字符的ascii值完成,從第一個字符開始。

  3. 您正在插入值ab而沒有任何id。在執行下面的更新語句之後,將id分配給val。通過使用類似的邏輯,您可以實現與before insert觸發器相同的操作。

第一個查詢確定new_id

select t.*, 
    (select count(*) from test t1 where t.val>=t1.val) + 
     o.diff as new_id 
from test t 
cross join 
(select * from 
    (select t.*,(select count(*) from test t1 where t.val>=t1.val) as rn , 
     id - (select count(*) from test t1 where t.val>=t1.val) as diff 
    from test t 
    ) where rn=1 
) o 

輸出

+------+-----+--------+ 
| id | val | new_id | 
+------+-----+--------+ 
| 2 | aa |  2 | 
| 3 | ac |  4 | 
| null | ab |  3 | 
+------+-----+--------+ 

我使用cross join因爲首先我們要確定的min_iddifference實際id。與上述情況一樣,如果我們生成的號碼從1n,您的ID以2開頭。所以這兩個diff1,我會用它來添加所有生成的ID,得到new_id。可能有一個更容易的方法,但這是我現在能想到的。

現在我們在更新聲明中使用此查詢來更新idnew_id

update test 
set id = (select tb.new_id from 
      (select t.*, 
       (select count(*) from test t1 where t.val>=t1.val) + 
        o.diff as new_id 
       from test t 
      cross join 
       (select * from 
        (select t.*,(select count(*) from test t1 where t.val>=t1.val) as rn , 
         id - (select count(*) from test t1 where t.val>=t1.val) as diff 
        from test t 
        ) where rn=1 
       ) o 
      ) tb 
      where test.val=tb.val 
     ) 
where exists 
    (select * From (select t.*, 
         (select count(*) from test t1 where t.val>=t1.val) + 
          o.diff as new_id 
         from test t 
        cross join 
         (select * from 
          (select t.*,(select count(*) from test t1 where t.val>=t1.val) as rn , 
           id - (select count(*) from test t1 where t.val>=t1.val) as diff 
          from test t 
          ) where rn=1 
         ) o 
        ) tb 
    where test.val=tb.val 
    ); 
相關問題