如何在 SQL Server 中无循环地更新列? [英] How to update the column without loop in SQL Server?

查看:28
本文介绍了如何在 SQL Server 中无循环地更新列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出于性能方面的考虑,我只需要删除循环并使用一些连接或其他解决方案来更新 #Result 表中的数据并获得循环返回的相同结果.

Due to performance perspective I just need to remove loop and using some joins or other solution to update the data in #Result table and get the same result which return by loop.

标量函数:

CREATE FUNCTION [MultiplyerScl]
    (@a INT, @b INT)
RETURNS INT
AS
BEGIN
    DECLARE @i AS INT = 2
    DECLARE @Value AS INT 

    IF (@b % @a = 0) 
    BEGIN
        SET @Value = @b
    END
    ELSE 
    BEGIN
        WHILE (1=1) 
        BEGIN
            IF((@b * @i) % @a = 0) 
            BEGIN
                SET @Value = @b * @i
                BREAK;
            END
            ELSE 
            BEGIN
                SET @i = @i + 1
            END
        END
    END

    RETURN @Value
END

餐桌设计及其价值.

CREATE TABLE #NUM (Groupid INT, GroupValue INT)

INSERT INTO #NUM 
VALUES (1, 8), (1, 9), (1, 23), (2, 5), (2, 5), (2, 10)

主循环逻辑.

SELECT 
    Groupid,
    GroupValue,
    MaxValue = MAX(GroupValue) OVER (PARTITION BY Groupid),
    MaxCount = COUNT(1) OVER(),
    RID = ROW_NUMBER() OVER (ORDER BY groupid)
INTO 
    #Result
FROM 
    #NUM 

DECLARE @i AS INT = 1
DECLARE @RawCnt AS INT = (SELECT MAX(MaxCount) FROM #Result)
DECLARE @iGroupid INT
DECLARE @iGroupvalue INT
DECLARE @iMaxValue INT

WHILE(@i <= @RawCnt) 
BEGIN
    SELECT 
        @iGroupid = Groupid,
        @iGroupvalue = Groupvalue,
        @iMaxValue = MaxValue 
    FROM 
        #Result 
    WHERE 
        RID = @i

    UPDATE #Result
    SET MaxValue = dbo.[MultiplyerScl](@iGroupvalue, @iMaxValue)
    WHERE Groupid = @iGroupid

    SET @i = @i + 1
END

SELECT * FROM #Result

推荐答案

试试这个

SELECT 
Groupid,
GroupValue,
MaxValue = MAX(GroupValue) OVER (PARTITION BY Groupid),
MaxCount = COUNT(1) OVER(),
RID = ROW_NUMBER() OVER (ORDER BY groupid)
INTO 
#Result
FROM 
#NUM

;WITH Res AS 
( 
SELECT Groupid, e.Groupvalue, dbo.[MultiplyerScl](Groupvalue, e.MaxValue) AS 
MaxValue, 1 AS i
FROM #Result e
UNION ALL 
--recursive execution 
SELECT e.Groupid, m.Groupvalue, dbo.[MultiplyerScl](e.Groupvalue, m.MaxValue) AS MaxValue, m.i + 1 AS i
FROM #Result e
INNER JOIN Res m ON e.Groupid = m.Groupid
WHERE dbo.[MultiplyerScl](e.Groupvalue, m.MaxValue) > m.MaxValue
)

SELECT Groupid, MAX(MaxValue) AS MaxValue
INTO #FinalResult
FROM Res
GROUP BY Groupid

UPDATE re
SET re.MaxValue = ire.MaxValue
FROM #FinalResult ire
INNER JOIN #Result re ON re.Groupid = ire.Groupid

SELECT * FROM #Result

这篇关于如何在 SQL Server 中无循环地更新列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆