回答

收藏

如何在SQL中表示并插入到有序列表中?

技术问答 技术问答 174 人阅读 | 0 人回复 | 2023-09-14

我想在SQL表中表示列表“ hi”,“ hello”,“再见”,“早安”,“ howdy”(按此顺序):" H0 H) v. Z9 ?* R$ L" W" g' h
pk | i | val! D3 r; V( i) W" g& {- b, h
------------
/ V9 R9 p) h$ u8 h2 k9 Q1  | 0 | hi
0 S, G/ X' U5 B$ \0  | 2 | hello
; d( F7 c, E& t* r: |  L5 P2  | 3 | goodbye
( y+ R  n$ H( _  M' D: M3  | 4 | good day
& B# i- w5 p# `) ^& ]5  | 6 | howdy
. C, Q9 A% p8 i3 `; Z9 r“ pk”是主键列。忽略其值。  e' o9 X9 ~& r/ |8 L$ N  G
“ i”是“索引”,用于定义“ val”列中值的顺序。它 仅 用于建立顺序,否则值并不重要。/ M- S6 y/ j6 H7 i7 {3 E5 R
我遇到的问题是在保持顺序的同时将值插入到列表中。例如,如果我想插入“嘿”,并且希望它出现 在 “你好”和“再见”之间,则我必须将“再见”和“早安”的“
3 p1 B/ E7 c3 P; {i”值转移(但最好不要将“你好”)为新条目腾出空间。
, ]4 f) k: ?  f- ?9 d7 N* U那么,是否有标准的SQL模式来执行移位操作,但仅移位必需的元素?(请注意,一个简单的“ UPDATE table SET i = i + 1 WHERE
1 a4 [/ H$ G) z9 X& y; ai> = 3”无效,因为它违反了对“ i”的唯一性约束,并且不必要地更新了“ howdy”行。)0 Z) B3 [0 k' a* y  S! Q
或者,有没有更好的方法来表示有序列表?我想您可以使“ i”为浮点值并在其中选择值,但是当不存在这样的值时,您必须进行单独的重新平衡操作。
% S& J- g3 x' w& h或者,如果我要将“ i”设为varchar,是否存在一些用于在任意其他字符串之间生成字符串值的标准算法?7 G* }& Q0 m. z* P4 L2 |5 K& p5 G3 C
还是应该将其表示为链接列表?我避免这样做是因为我也希望能够执行SELECT .. ORDER BY来按顺序获取所有元素。# d! d3 z3 w1 c: L
                7 ^( g, M% c! h# Q
解决方案:6 Q) Y" P/ ~& |* M: C
               
5 Q6 c* ]2 |& M  d2 M0 q2 b, h% ^/ D$ @+ ^4 z6 e

! D- k$ Y) \; o5 ?; Y                您可以通过使用级联触发器轻松地实现此目的,该触发器将与插入/更新操作中的新索引条目相等的任何“索引”条目更新为索引值+1。这将级联所有行,直到第一个间隙停止级联-) X1 g7 d+ D% F: i3 g
有关PostgreSQL实现,请参见此博客条目中的第二个示例。2 r% q5 P$ y$ l4 [. ?% I+ O0 l% J; ?
该方法应独立于所使用的RDBMS起作用,前提是它支持 在 更新/插入 之前
2 v' I- F5 ]7 c& x" q4 v  t2 \触发的触发器。如果您在代码中实现了所需的行为(增加所有后续索引值,直到遇到间隔),则基本上可以完成您的工作,但是以一种更简单,更有效的方式进行。
7 \# i* M. C, L  |7 N4 W! }2 t0 E或者,如果您可以使用SQL Server的限制,请检查architectureid类型。虽然主要用于定义嵌套层次结构,但也可以将其用于平面排序。它有点类似于您使用浮点数的方法,因为它允许通过分配小数值来在两个位置之间插入,从而避免了更新其他条目的需要。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则