我们有一个如下所示的数据库表:
RowID CustomerID Priority Data
11 123 1 {some data}
2 123 1 {some data}
3 123 3 {some data}
44 456 1 {some data}
5 456 2 {some data}
61 456 2 {some data}
65 456 2 {some data}
76 456 2 {some data}
96 456 3 {some data}
36 456 4 {some data}
7 123 1 {some data}
这是应该按优先级排序的项目列表。不幸的是,由于系统错误(代码和不正确的约束),一些优先级是重复的。
例如,在我给出的示例中,客户456有三个优先级为2
的项目。不幸的是,目前还没有办法知道哪一个实际上应该在插槽2
中。
显然,需要纠正系统以防止出现这种情况(并且这已经完成),但我们仍然需要解决客户数据情况。在这个例子中,如果我们专注于修复客户#456的数据,我们能够提出的最佳解决方案是将456行更改为:
RowID CustomerID Priority Data
44 456 1 {some data}
5 456 2 {some data}
61 456 3 {some data}
65 456 4 {some data}
76 456 5 {some data}
96 456 6 {some data}
36 456 7 {some data}
您可以看到优先级增加如下:
这会将数据恢复到没有两个项目共享相同优先级的情况。
我想知道是否有办法在SQL中解决这个问题,或者我是否必须编写一个“修复它”程序来分析一个客户的数据库。
尽我所能,我似乎无法理解如何在直接的SQL中实现这一点。有可能吗?
答案 0 :(得分:1)
所以你想按customerId,priority,rowId订购,并为每个客户设置优先级1,2,3,4 ......等等,如下面的查询
首先看看newPriority是否是您想要的每一行(sqlFiddle)
SELECT rowId,customerId,priority
IF(@prevCustomer <> customerId,@priority:=1,@priority:=@priority+1)
AS newPriority,
@prevCustomer:=customerId
FROM YourTable,
(SELECT @priority:=0,@prevCustomer:=0)dummy
ORDER BY customerId,priority,rowId
然后如果这是正确的,请检查newPriority列并查看,您可以在下面运行更新(sqlFiddle)
UPDATE yourTable T1
INNER JOIN
(SELECT rowId,customerId,priority
IF(@prevCustomer <> customerId,@priority:=1,@priority:=@priority+1)
AS newPriority,
@prevCustomer:=customerId
FROM YourTable,
(SELECT @priority:=0,@prevCustomer:=0)dummy
ORDER BY customerId,priority,rowId
)T2
ON T1.rowId = T2.rowId
SET T1.priority = T2.newPriority;
要仅修复客户456 ,您可以在查询结尾添加WHERE T1.customerId=456
,如下所示
UPDATE yourTable T1
INNER JOIN
(SELECT rowId,customerId,priority,
IF(@prevCustomer <> customerId,@priority:=1,@priority:=@priority+1)
AS newPriority,
@prevCustomer:=customerId
FROM YourTable,
(SELECT @priority:=0,@prevCustomer:=0)dummy
ORDER BY customerId,priority,rowId
)T2
ON T1.rowId = T2.rowId
SET T1.priority = T2.newPriority
WHERE T1.customerId = 456;
答案 1 :(得分:0)
我建议您在事务中放置任何SQL,然后选择所有行以直观地查看它是否是您想要的。然后回滚。只有当您确定其正确时,才将其更改为提交。这样,您就不会破坏数据库数据。或者(并且更好)备份您的数据库,以便您可以恢复它,如果你搞砸了。缺点是如果您需要进行恢复,备份后任何客户都会更改数据库。