比较同一表中的2个连续行,并使用row1值更新row2

时间:2012-06-07 18:44:08

标签: sql-server-2005

我需要比较同一个表中的2个连续行。如果第二行中缺少数据,我应该用第一行的数据更新它。

例如:

Row   EmpID  DATE        PosID        EmpStatus  EmpDept  EmpVP
----------------------------------------------------------------------
1     21     2010-12-31  NULL         TC         NULL     40
2     21     2010-01-25  90156840101  NULL       407      NULL
3     21     2003-11-25  NULL         AC         NULL     NULL

第一次迭代:由于Row1 EmpStatus = TC,我想将Row2上的EmpStatus更新为TC(因为它为NULL)并在Row2上将EmpVP更新为40,如下所示:

Row   EmpID  DATE        PosID        EmpStatus  EmpDept  EmpVP
----------------------------------------------------------------------
1     21     2010-12-31  NULL         TC          NULL    40
2     21     2010-01-25  90156840101  TC          407     40 
3     21     2003-11-25  NULL         AC          NULL    NULL

第二次迭代:由于Row3上的PositionID为NULL,我想用Row2的PositionID更新Row3。由于Row2现在有EmpStatus = TC,我想比较row2和row3数据。由于Row3有一个新值,我想保留新值“AC”。但同时我想更新Row3 = 40的EmpDept的值,因为它是NULL。所需的结果如下所示:

Row   EmpID  DATE        PosID        EmpStatus  EmpDept  EmpVP
----------------------------------------------------------------------
1     21     2010-12-31  NULL         TC          NULL    40
2     21     2010-01-25  90156840101  TC          407     40 
3     21     2003-11-25  90156840101  AC          407     40

我正在处理历史数据加载,我必须根据日期建立记录。

任何人都可以告诉我如何编码吗? 我想知道我们是否可以进行这些更新,最好不使用游标,因为我在这个表中有很多员工。

非常感谢!

1 个答案:

答案 0 :(得分:1)

这是一个迭代过程,它不仅取决于所访问的每一行,还取决于处理过程中所做的数据更改。我甚至无法想象如果没有游标你会怎么做。

我认为一旦你决定使用游标,那么只需要确定规则(以比你提出的更一般的方式),然后使用游标实现这些规则。

这似乎是一次性过程,所以我不确定我是否理解为什么你会担心编写一个使用游标来处理数据的例程,并在维护期间或者在维护期间运行它缓慢使用期。

以下是一些关于如何解决此问题的伪代码(您需要从手册中获取实际语法详细信息,并且需要确保以正确的顺序和正确的方式应用业务规则) :

BEGIN

DECLARE @row NUMBER, @posID VARCHAR(20), @empStatus VARCHAR(2), @empDept NUMBER, @empVP NUMBER;
DECLARE @prevPosID VARCHAR(20), @prevEmpStatus VARCHAR(2), @prevEmpDept NUMBER, @prevEmpVP NUMBER;
DECLARE @isFirst NUMBER;
SET @isFirst = 1;

DECLARE  mycurs CURSOR FOR
SELECT   Row, PosID, EmpStatus, EmpDept
FROM     Empl
ORDER BY Date DESC
FOR UPDATE OF Empl;

OPEN mycurs;

FETCH NEXT mycurs INTO @row, @posID, @empStatus, @empDept, @empVP;

WHILE (@@FETCH_STATUS != NOTFOUND)
BEGIN
    IF (@isFirst == 1) THEN
    BEGIN
        @isFirst = 0;
    END
    ELSE
    BEGIN
        IF (@empStatus IS NULL AND @prevEmpStatus IS NOT NULL) THEN
        BEGIN
            SET @empStatus = @prevEmpStatus;
            UPDATE Empl SET EmpStatus = @empStatus WHERE Row = @row;
        END
        IF (@posID IS NULL AND @prevPosID IS NOT NULL) THEN
        BEGIN
            SET @posID = @prevPosID ;
            UPDATE Empl SET PosID = @posID WHERE Row = @row;
        END
        IF (@empDept IS NULL AND @prevEmpDept  IS NOT NULL) THEN
        BEGIN
            SET @empDept = @prevEmpDept;
            UPDATE Empl SET EmpDept= @empDept WHERE Row = @row;
        END
    END

    SET @prevPosID = @posID;
    SET @prevEmpStatus = @empStatus;
    SET @prevEmpDept = @empDept;
    SET @prevEmpVP = @empVP;

    FETCH NEXT mycurs INTO @row, @posID, @empStatus, @empDept, @empVP;
END

DEALLOCATE mycurs;
CLOSE mycurs;

END