Sql 更新组中两列之间相关记录的唯一编号
我需要识别和更新与Req_结果列下的排名相关的相关记录,如下所示。 表名为tblSource +---+---+---------+-----+ |项目|密钥| Denserankwrt密钥|请求| Res| +---+---+---------+-----+ |a | 1 | 1 | 1| +---+---+---------+-----+ |a | 2 | 2 | 1| +---+---+---------+-----+ |a | 3 | 3 | 1| +---+---+---------+-----+ |b | 2 | 2 | 1| +---+---+---------+-----+ |b | 9 | 7 | 1| +---+---+---------+-----+ |c | 1 | 1 | 1| +---+---+---------+-----+ |c | 6 | 5 | 1| +---+---+---------+-----+ |d | 5 | 4 | 4| +---+---+---------+-----+ |e | 8 | 6 | 6| +---+---+---------+-----+ |f | 2 | 2 | 1| +---+---+---------+-----+ |f | 6 | 5 | 1|Sql 更新组中两列之间相关记录的唯一编号,sql,sql-server,Sql,Sql Server,我需要识别和更新与Req_结果列下的排名相关的相关记录,如下所示。 表名为tblSource +---+---+---------+-----+ |项目|密钥| Denserankwrt密钥|请求| Res| +---+---+---------+-----+ |a | 1 | 1 | 1| +---+---+---------+-----+ |a | 2 | 2 | 1| +---+---+---------+-----+ |a | 3 | 3 | 1| +---+---+---------
+---+---+---------+-----+ 不能在单个语句中执行更新
CREATE TABLE #Table
(
Id INT
,Item varchar(30)
,[key] INT
,DenseRankWrtKey INT
,Req_Res INT
)
INSERT INTO #Table
(
Item
,[key]
,DenseRankWrtKey
)
VALUES
<YOUR DATA>
;WITH CTE
AS
(
SELECT
T.Item
,T.[Key]
,Id = RANK() OVER(order by T.DenseRankWrtKey,T.Item)
FROM
#Table AS T
)
UPDATE
T
SET
T.Id = CTE.Id
FROM
CTE
INNER JOIN #Table AS T ON T.Item = CTE.Item AND T.[key] = CTE.[key]
DECLARE @LoopVal INT = 0
,@LoopReq INT = NULL
,@LoopKey VARCHAR(50) = NULL
WHILE 1 = 1
BEGIN
SELECT TOP 1
@LoopVal = T.DenseRankWrtKey
,@LoopReq = T.Req_Res
FROM
#Table AS T
WHERE
T.DenseRankWrtKey > @LoopVal
ORDER BY
T.DenseRankWrtKey ASC
IF @@ROWCOUNT = 0
BREAK;
UPDATE T2
SET Req_Res = CASE WHEN @LoopReq IS NOT NULL THEN @LoopReq ELSE T.DenseRankWrtKey END
FROM
#Table AS T
INNER JOIN #Table AS T2 ON T.[key] = T2.[key]
WHERE
T.DenseRankWrtKey = @LoopVal
AND T2.Req_Res IS NULL
UPDATE
T
SET
T.Req_Res = CASE WHEN @LoopReq IS NOT NULL THEN @LoopReq ELSE T2.Req_Res END
FROM
#Table AS T
INNER JOIN #Table AS T2 ON T.Item = T2.Item
AND T2.Req_Res IS NOT NULL
AND T.Req_Res IS NULL
END
SELECT * FROM #Table
ORDER BY
DenseRankWrtKey
DROP TABLE #Table
GO
不能在单个语句中执行更新
CREATE TABLE #Table
(
Id INT
,Item varchar(30)
,[key] INT
,DenseRankWrtKey INT
,Req_Res INT
)
INSERT INTO #Table
(
Item
,[key]
,DenseRankWrtKey
)
VALUES
<YOUR DATA>
;WITH CTE
AS
(
SELECT
T.Item
,T.[Key]
,Id = RANK() OVER(order by T.DenseRankWrtKey,T.Item)
FROM
#Table AS T
)
UPDATE
T
SET
T.Id = CTE.Id
FROM
CTE
INNER JOIN #Table AS T ON T.Item = CTE.Item AND T.[key] = CTE.[key]
DECLARE @LoopVal INT = 0
,@LoopReq INT = NULL
,@LoopKey VARCHAR(50) = NULL
WHILE 1 = 1
BEGIN
SELECT TOP 1
@LoopVal = T.DenseRankWrtKey
,@LoopReq = T.Req_Res
FROM
#Table AS T
WHERE
T.DenseRankWrtKey > @LoopVal
ORDER BY
T.DenseRankWrtKey ASC
IF @@ROWCOUNT = 0
BREAK;
UPDATE T2
SET Req_Res = CASE WHEN @LoopReq IS NOT NULL THEN @LoopReq ELSE T.DenseRankWrtKey END
FROM
#Table AS T
INNER JOIN #Table AS T2 ON T.[key] = T2.[key]
WHERE
T.DenseRankWrtKey = @LoopVal
AND T2.Req_Res IS NULL
UPDATE
T
SET
T.Req_Res = CASE WHEN @LoopReq IS NOT NULL THEN @LoopReq ELSE T2.Req_Res END
FROM
#Table AS T
INNER JOIN #Table AS T2 ON T.Item = T2.Item
AND T2.Req_Res IS NOT NULL
AND T.Req_Res IS NULL
END
SELECT * FROM #Table
ORDER BY
DenseRankWrtKey
DROP TABLE #Table
GO
我发现这种方式更容易阅读和维护
DECLARE @TestTable TABLE (Item CHAR(1), ItemKey INT, DenseRankWrtKey INT, Req_Res INT)
INSERT @TestTable (Item, ItemKey, DenseRankWrtKey) VALUES
('a' , 1 , 1)
, ('a' , 2 , 2)
, ('a' , 3 , 3)
, ('b' , 2 , 2)
, ('b' , 9 , 7)
, ('c' , 1 , 1)
, ('c' , 6 , 5)
, ('d' , 5 , 4)
, ('e' , 8 , 6)
, ('f' , 2 , 2)
, ('f' , 6 , 5)
DECLARE @OtpTable TABLE (Item CHAR(1), ItemKey INT, DenseRankWrtKey INT)
DECLARE @RC INT = 1
WHILE @RC > 0
BEGIN
DELETE @OtpTable
;WITH UpdateCTE AS (
SELECT TOP 1 * from @TestTable
WHERE Req_Res IS NULL
)
UPDATE UpdateCTE
set Req_Res = DenseRankWrtKey
OUTPUT Inserted.Item, Inserted.ItemKey, inserted.DenseRankWrtKey INTO @OtpTable
SET @RC = @@ROWCOUNT
WHILE @@ROWCOUNT > 0
UPDATE T
SET Req_Res = (SELECT TOP 1 DenseRankWrtKey FROM @OtpTable)
OUTPUT Inserted.Item, Inserted.ItemKey, inserted.DenseRankWrtKey INTO @OtpTable
FROM @TestTable T
WHERE T.Req_Res IS NULL AND EXISTS (SELECT 1 FROM @OtpTable OT WHERE (T.Item = OT.Item OR T.ItemKey = OT.ItemKey))
END
SELECT * FROM @TestTable
我发现这种方式更容易阅读和维护
DECLARE @TestTable TABLE (Item CHAR(1), ItemKey INT, DenseRankWrtKey INT, Req_Res INT)
INSERT @TestTable (Item, ItemKey, DenseRankWrtKey) VALUES
('a' , 1 , 1)
, ('a' , 2 , 2)
, ('a' , 3 , 3)
, ('b' , 2 , 2)
, ('b' , 9 , 7)
, ('c' , 1 , 1)
, ('c' , 6 , 5)
, ('d' , 5 , 4)
, ('e' , 8 , 6)
, ('f' , 2 , 2)
, ('f' , 6 , 5)
DECLARE @OtpTable TABLE (Item CHAR(1), ItemKey INT, DenseRankWrtKey INT)
DECLARE @RC INT = 1
WHILE @RC > 0
BEGIN
DELETE @OtpTable
;WITH UpdateCTE AS (
SELECT TOP 1 * from @TestTable
WHERE Req_Res IS NULL
)
UPDATE UpdateCTE
set Req_Res = DenseRankWrtKey
OUTPUT Inserted.Item, Inserted.ItemKey, inserted.DenseRankWrtKey INTO @OtpTable
SET @RC = @@ROWCOUNT
WHILE @@ROWCOUNT > 0
UPDATE T
SET Req_Res = (SELECT TOP 1 DenseRankWrtKey FROM @OtpTable)
OUTPUT Inserted.Item, Inserted.ItemKey, inserted.DenseRankWrtKey INTO @OtpTable
FROM @TestTable T
WHERE T.Req_Res IS NULL AND EXISTS (SELECT 1 FROM @OtpTable OT WHERE (T.Item = OT.Item OR T.ItemKey = OT.ItemKey))
END
SELECT * FROM @TestTable
对于较大的表,它给出了错误的结果。不需要id。添加id只是为了循环目的。您可以使用任何现有的唯一列。对于更大的表格,你可以分享更多的数据。谢谢阿卡什,还可以查看编辑过的问题表格,我发现现在很难得到答案。同样的逻辑也可以。我刚刚按T项添加了订单。请检查更新后的答案…如果我添加此代码,则其他结果将为空。对于较大的表,它将给出错误的结果。不需要id。添加id只是为了循环目的。您可以使用任何现有的唯一列。对于更大的表格,你可以分享更多的数据。谢谢阿卡什,还可以查看编辑过的问题表格,我发现现在很难得到答案。同样的逻辑也可以。我刚刚按T项添加了订单。请检查更新的答案…如果我添加此代码,则其他结果将被取消您的问题不清楚。例如,您的第二组数据没有预期的结果。它没有重复的项目,我认为这对问题很重要,所以奇怪的是样本数据没有任何例子。你的问题不清楚。例如,您的第二组数据没有预期的结果。它没有重复项,我认为这对问题很重要,所以奇怪的是,样本数据没有任何例子。