[英]SQL: insert to unique column with shift
我需要使用 varchar 名称和 Integer intValue 存储数据。 所有整数值都是唯一的,我需要遵守该合同
我需要使用以下规则编写查询以添加元素:如果插入后存在 intValue 重复 - 我们需要增加现有元素的 intValue 以解决冲突。 重复该操作,直到没有冲突为止。
例子:
B | 2 | | B | 2 |
C | 3 | | E | 3 |
D | 4 | => insert (E 3) => | C | 4 |
A | 1 | | D | 5 |
Z | 7 | | A | 1 |
| Z | 7 |
唯一的想法是在循环中运行更新查询,但这看起来效率太低了。
我需要在 Spring JPA 中编写这个查询,所以唯一的要求是查询不应该是特定于数据库的
假设队列中有一个人。 而 intValue 是队列中的位置。 因此,“添加”意味着有人来付钱并说:我不想成为队列中的最后一个。 例如,我想成为第三个。 所以你拿了钱,把那个人放在一个队列中,这样其他人在他之后 - 增加他们的位置。
与队列的唯一区别 - 在我的情况下允许有间隙
啊哈,我们可以说是由于人们离开队列而造成的。
让我们试试这个。 循环是不可避免的——要么是服务器做的,要么我们可以像 SQL 一样做。
-- prepare test data
declare @PeopleQueue table (pqname varchar(100), intValue int);
insert into @PeopleQueue
SELECT 'B' AS pqname, 2 as intValue UNION ALL
SELECT 'C' AS pqname, 3 as intValue UNION ALL
SELECT 'D' AS pqname, 4 as intValue UNION ALL
SELECT 'A' AS pqname, 1 as intValue UNION ALL
SELECT 'Z' AS pqname, 7 as intValue
;
--SELECT '' AS pqname, 0 as intValue UNION ALL
Select * from @PeopleQueue; - verify good test data
-- Solve the problem
Declare @pqnameNEW varchar(100) = 'E';
Declare @intNEW int = 3; -- 3 for conflict, or for no conflict, use 13
Declare @intHIGH int;
IF EXISTS ( SELECT 1 FROM @PeopleQueue WHERE intValue = @intNEW )
BEGIN
-- find the end of the sequence, before the gap
SET @intHIGH = (
SELECT TOP 1
intValue
FROM @PeopleQueue pq
WHERE NOT EXISTS
(
SELECT NULL
FROM @PeopleQueue pn
WHERE pn.intValue = pq.intValue + 1
)
AND pq.intValue >= @intNEW
)
;
-- now Update all from intNEW thru intHIGH
UPDATE @PeopleQueue
SET intValue = intValue + 1
WHERE intValue >= @intNEW
AND intValue <= @intHIGH
End;
-- finally insert the new item
INSERT into @PeopleQueue Values (@pqnameNEW, @intNEW);
Select * from @PeopleQueue; -- verify correct solution
编辑--11/28 17:00 或者,估计 Bump-the-Line-Inserts 的数量(vs 附加到末尾插入),并将 intValues 设计为最初是十 (10) 的倍数,以便长序列更新被最小化。
update queue
SET intValue = intValue + 1
WHERE intValue >= 3
AND intValue <= (
SELECT q1.intValue
FROM queue as q1 LEFT JOIN queue AS q2 ON q1.intValue + 1 = q2.intValue
WHERE q2.name is NULL AND q1.intValue > 3
ORDER BY q1.intValue
LIMIT 1
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.