Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 更新组中两列之间相关记录的唯一编号_Sql_Sql Server - Fatal编程技术网

Sql 更新组中两列之间相关记录的唯一编号

Sql 更新组中两列之间相关记录的唯一编号,sql,sql-server,Sql,Sql Server,我需要识别和更新与Req_结果列下的排名相关的相关记录,如下所示。 表名为tblSource +---+---+---------+-----+ |项目|密钥| Denserankwrt密钥|请求| Res| +---+---+---------+-----+ |a | 1 | 1 | 1| +---+---+---------+-----+ |a | 2 | 2 | 1| +---+---+---------+-----+ |a | 3 | 3 | 1| +---+---+---------

我需要识别和更新与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|
+---+---+---------+-----+ 不能在单个语句中执行更新

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项添加了订单。请检查更新的答案…如果我添加此代码,则其他结果将被取消您的问题不清楚。例如,您的第二组数据没有预期的结果。它没有重复的项目,我认为这对问题很重要,所以奇怪的是样本数据没有任何例子。你的问题不清楚。例如,您的第二组数据没有预期的结果。它没有重复项,我认为这对问题很重要,所以奇怪的是,样本数据没有任何例子。