我想在数据库中维护一个整数字段以显示顺序,这将是唯一的(显而易见的)
现在假设我在数据库中有10条记录,如果我将更新第10条记录并将显示顺序从10设置为1,那么从1到9的所有记录将增加1,如 显示顺序1将变为2,2至3,3至4,4至5 ......
那么如何保持这个?
想要任何优化解决方案,如果我们有1000条记录,那么我们就无法为所有999条记录启动更新查询。
请帮帮我
答案 0 :(得分:2)
您可以使用更大的值进行显示,例如:
apple : 1 000 000
orange : 2 000 000
banana : 3 000 000
现在,如果我想在位置2(n = 2)添加potato
,我会采用n(=> 2:橙色)和(n-1)(=> 1:apple)位置和除法他们以2来获得新的马铃薯位置:
(1 000 000 + 2 000 000)/ 2
= 1 500 000
apple : 1 000 000
**potato : 1 500 000**
orange : 2 000 000
banana : 3 000 000
这将花费很长时间,如果在某些时候你觉得你已经用尽了这个模式,你仍然可以将所有值乘以1000。
您可以继续使用低值(1,2,3,...)并将其类型定义为DOUBLE
,因此在将它们除以2时它们永远不会发生碰撞。
编辑:关于将香蕉放在第1位:
使用公式(n +(n-1))/ 2:
这里n = 1(新职位)。
我们的数据是:
apple : 1 000 000
potato : 1 500 000
orange : 2 000 000
banana : 3 000 000
(1 000000+(0))/ 2
= 500 000
我将订单500 000给香蕉:
**banana : 500 000**
apple : 1 000 000
potato : 1 500 000
orange : 2 000 000
另一种解决方案:创建一个文本字段,该字段将成为索引器并包含所有ID。
“1,2,3,4,5,6,7”
现在如果我想将元素id 8放在3和4之间,我只需要将“,4”替换为“,8,4”。
虽然在计算方面找到索引n处的元素比较复杂,所以我个人使用第一个解决方案。
答案 1 :(得分:1)
为什么不尝试使用功能或存储过程 ..这两个对于处理这种情况非常酷。让我们尝试下面的一个..希望它会帮助你。
请记住我正在考虑遵循两个参数
table name - DisplayOrder
column name to reorder = O_nbr
如果您需要将O_nbr(订单号)从10转换为1,您只需将方法调用为
select UpdateOrder(10,1);
// it will return you the proper message either updated or not.. or whatever
功能代码如下 -
DELIMITER $$
create function UpdateOrder (fromOrder int, toOrder int)
RETURNS varchar(50)
DETERMINISTIC
BEGIN
DECLARE reslt varchar(50);
DECLARE rowCount int;
SET reslt = 'Error Occured.';
if( fromOrder < 1) then
SET reslt='fromOrder can not be less then 1';
elseif(toOrder < 1) then
SET reslt='toOrder can not be less then 1';
else
select count(*) into rowCount from DisplayOrder;
if(rowCount < fromOrder) then
SET reslt = concat('Sorry check again, we have only ',rowCount, ' records');
elseif(rowCount < toOrder) then
SET reslt = concat('Sorry check again, we have only ',rowCount, ' records');
else
if(fromOrder = toOrder) then
SET reslt = 'No Changes were made.';
else
if(fromOrder > toOrder) then
update DisplayOrder set O_nbr = 0 where O_nbr = fromOrder;
Update DisplayOrder set O_nbr = O_nbr+1 where O_nbr < fromOrder AND O_nbr > (toOrder-1) order by O_nbr desc;
update DisplayOrder set O_nbr = toOrder where O_nbr = 0;
end if;
if(fromOrder < toOrder) then
update DisplayOrder set O_nbr = 0 where O_nbr = fromOrder;
Update DisplayOrder set O_nbr = O_nbr-1 where O_nbr > fromOrder AND O_nbr < (toOrder+1) order by O_nbr asc;
update DisplayOrder set O_nbr = toOrder where O_nbr = 0;
end if;
SET reslt = 'Successfully done';
end if;
end if;
end if;
RETURN reslt;
END$$
DELIMITER ;
您可以将 DisplayOrder 替换为您的表格nane,将 O_nbr 替换为您的列名称以重新排序
复制代码并在你的mysql数据库查询窗口中运行..然后移动顺序( O_nbr在DisplayOrder表中)使用上述签名..
Select UpdateOrder(fromOrder, toOrder);
如果您尝试使用0或更小的值或任何不合适的条件运行,它将返回错误消息
Select UpdateOrder(10, 0);
//returns "toOrder can not be less then 1"
Select UpdateOrder(11, 1);
//return "Sorry check again, we have only 10 records"
Select UpdateOrder(5, 5);
//returns "No Changes were made."
如果你传递了正确的参数..
Select UpdateOrder(10, 2);
//returns "Successfully done"
答案 2 :(得分:0)
您可以按任意顺序显示数据,而无需更改数据库中的id
字段值
我认为没有必要向最终用户显示ID
的值,但仅用于内部参考。
您可以尝试这样:
select * from my_table
order by field( id, 10 ), id asc
这会导致在id
上按10
值ascending
获取行,其他行以field
顺序获取。
您可以在{{1}}中指定任意数量的值,以便在结果顶部按特定顺序显示。