我有2张桌[Pubs]和[作者]。 [Pubs}可以有很多[作者]和[作者]可以创作很多[Pubs]所以我创建了一个联结表[Pub_Authors]来处理多对多关系。
每位作者都会在酒吧中获得优先权,并且主要作者或出版经理会不时地为作者重新分配新的优先权。
TABLE STRUCTURE:
PA_ID INT
PUB_ID INT
AUTH_ID INT
PA_PRIORITY INT
OLD_PRI (I added this based on a possible solution found here)
问题: 当主要作者重新分配优先级时,我需要重新编号其余的作者'从那时起,该酒吧的优先事项。
PA_ID PUB_ID AUTH_ID PA_PRIORITY O_PRI
1 11 10 1 1
2 11 20 2 2
3 11 30 3 3
上面的示例显示了包含3位作者的ONE pub的数据。 出版经理将AUTHOR 20的优先级从2更改为3。
应该发生什么:
PA_ID PUB_ID AUTH_ID PA_PRIORITY O_PRI
1 11 10 1 1
2 11 20 3 2
3 11 30 2 3
这是我在另一个例子中找到的SP,但它并没有完全符合我的要求...它将所有优先级更改为" 3&#34 ;而不是重新排序。
ALTER Proc update_Publication_Author_Priority_Order (@ID Int, @NewPosition Int = 1)
As
Declare @OldPosition Int,
@Direction Int
Select @OldPosition = PA_PRIORITY
From Pub_Authors
Where PUB_ID = @ID
Set @Direction = Case
When @OldPosition < @NewPosition Then 0
When @OldPosition > @NewPosition Then 1
Else -1
End
Update t
Set oldPri = PA_PRIORITY ,
PA_PRIORITY = Case
When PUB_ID = @ID Then @NewPosition
When @Direction = 0 And
PA_PRIORITY Between @OldPosition And @NewPosition Then PA_PRIORITY - 1
When @Direction = 1 And
PA_PRIORITY Between @NewPosition And @OldPosition Then PA_PRIORITY + 1
Else PA_PRIORITY
End
From Pub_Authors t
我确定有一个简单的解决方案,我忽略了......任何帮助都会受到赞赏。
谢谢, 鲍勃
好的......经过认真考虑,反复试验,这就是我提出的可能的解决方案。我现在的问题是CASE声明中的多个指令......
Update t
Set oldPri = PA_Priority,
PA_Priority = Case -- add a counter and increment within the loop.
When PA_Priority < @NewPosition Then PA_Priority
@Counter + 1
When PA_Priority = @NewPosition Then @Counter
@Counter + 1
When PA_Priority > @NewPosition Then @Counter
@Counter + 1
Else PA_Priority
@Counter + 1
End
来自Pub_Authors t 其中PUB_ID IN(选择publicationID 来自Pub_Authors Pub_ID = @ID)
答案 0 :(得分:1)
纠正你已经拥有的最简单的方法就是修复一些地方。
Select @OldPosition = PA_PRIORITY
From Pub_Authors
Where PUB_ID = @ID
应该是
Select @OldPosition = PA_PRIORITY
From Pub_Authors
Where PA_ID = @ID
然后您的更新WHERE需要更改以获取正确的pub_ids并且第一个CASE需要查看PA_ID
UPDATE t
SET oldPri = PA_PRIORITY,
PA_PRIORITY = CASE WHEN PA_ID = @ID THEN @NewPosition
WHEN @Direction = 0
AND PA_PRIORITY BETWEEN @OldPosition AND @NewPosition THEN PA_PRIORITY - 1
WHEN @Direction = 1
AND PA_PRIORITY BETWEEN @NewPosition AND @OldPosition THEN PA_PRIORITY + 1
ELSE PA_PRIORITY
END
FROM Pub_Authors t
WHERE PUB_ID IN (SELECT PUB_ID
FROM Pub_Authors
WHERE PA_ID = @ID)
您也可以使用ROW_NUMBER执行此操作。我已经对它进行了几次测试,似乎有效。
CREATE PROCEDURE update_Publication_Author_Priority_Order (
@ID INT,
@NewPosition INT = 1
)
AS
BEGIN
WITH cte AS
(
SELECT *,
ROW_NUMBER() OVER (ORDER BY CASE WHEN PA_ID = @ID THEN @NewPosition ELSE [PA_PRIORITY] END, [PA_PRIORITY] DESC) Rn
FROM Pub_Authors
WHERE PUB_ID IN (SELECT PUB_ID FROM Pub_Authors WHERE PA_ID = @ID)
)
UPDATE cte SET [PA_PRIORITY] = Rn, [O_PRI] = [PA_PRIORITY];
END
GO
答案 1 :(得分:0)
所以基本上你的问题是如何在表中保留一个可更新的订单列。最简单的方法是将oreder保存在数字列而不是int列中,这样您就可以将任何记录设置到任何地方而不更新talbe中的任何其他行。假设您要将第四条记录移至第二位。您所要做的就是将它的数字更新为1.5。