仅限Microsoft SQL Server游标

时间:2016-02-10 17:29:28

标签: sql-server

我希望仅使用Cursor来提升。我在下面有一个小表,基本上我想要做的是在MS SQL Server中写一个光标来比较两个日期记录。如果两个日期之间的差异小于5天,那么我想保留两个日期中较早的日期。如果两个日期间隔超过5天,那么我想保留两者,光标应继续比较下一条记录,依此类推。然而,它没有像我预期的那样工作。我从Cursor中寻找的输出是一个名为Final14的表,其中的记录旁边有“Keep”字样。

我添加了第三列,以显示应保留哪个日期。

SQL列

Name    Date    
Mary    2/2/2016    Keep
Mary    2/3/2016    Delete
Mary    2/5/2016    Keep
Mary    2/11/2016   keep
Mary    2/17/2016   Keep
Mary    2/19/delete delete

我的光标如下:

/*
CREATE TABLE FIND14 --DROP TABLE FIND14
(
    Name NVARCHAR(20)
    , DATE1 DATETIME
)
;

CREATE TABLE FINAL14
(
    Name NVARCHAR(20)
    , DATE1 DATETIME
)

INSERT INTO FIND14(Name, DATE1)
VALUES('Mary', '2/2/2016'), ('Mary', '2/3/2016'), ('Mary', '2/5/2016'), ('Mary', '2/11/2016')
, ('Mary', '2/17/2016'), ('Mary', '2/19/2016')
*/

TRUNCATE TABLE FINAL14;

DECLARE @Member1 NVARCHAR(20), @SD1 DATETIME
DECLARE @Member2 NVARCHAR(20), @SD2 DATETIME

DECLARE CDATE CURSOR
FOR

    SELECT Name, DATE1
    FROM FIND14 

    ORDER BY DATE1

OPEN CDATE

    FETCH NEXT FROM CDATE INTO @Member1, @SD1 
    FETCH NEXT FROM CDATE INTO @Member2, @SD2 

WHILE(@@FETCH_STATUS = 0)

    BEGIN

        IF DATEDIFF(dd, @SD1, @SD2) < 5

            BEGIN

                INSERT INTO FINAL14

                    SELECT @Member1, @SD1
                    FROM FIND14

            END

        ELSE 

            IF DATEDIFF(dd, @SD1, @SD2) >= 5

            BEGIN

                    INSERT INTO FINAL14

                    SELECT DISTINCT @Member1, @SD1
                    FROM FIND14
                    ;

                    INSERT INTO FINAL14

                    SELECT DISTINCT @Member2, @SD2
                    FROM FIND14

            END

FETCH NEXT FROM CDATE INTO @Member1, @SD1
END

CLOSE CDATE
DEALLOCATE CDATE
;

SELECT * FROM FIND14

OUTPUT应如下所示:

Name    Date    
Mary    2/2/2016    Keep
Mary    2/5/2016    Keep
Mary    2/11/2016   keep
Mary    2/17/2016   Keep

1 个答案:

答案 0 :(得分:0)

对于插入,由于只插入变量,因此请使用VALUES而不是SELECT:

                INSERT INTO FINAL14
                VALUES (@Member1, @SD1)
                ;

编辑:

好的,既然我明白你总是想在做一个比较之后跳到下一行的行,那么你只需要在循环的末尾添加一行来获取下一行的行,而不是只是下一行。所以你需要替换它:

    FETCH NEXT FROM CDATE INTO @Member1, @SD1 
END

有了这个:

    FETCH NEXT FROM CDATE INTO @Member1, @SD1 
    FETCH NEXT FROM CDATE INTO @Member2, @SD2 
END

就像你开始循环之前一样。