类似于游标

时间:2016-04-08 00:43:06

标签: sql-server

我正在尝试使用update语句来遍历表的行,并为每行的单个列分配一个值,具体取决于先前值和当前值的比较方式,这与游标的工作方式类似。 / p>

初始表数据:

|PK|EffectiveDate|ChangeDate|ActionType|
| 1|   2015-01-01|      NULL|       Add|
| 2|   2015-03-01|2015-03-01|    Change|
...

所以,这是我的代码:

declare @prevPK int = null
        , @prevEffDate date = null
        , @prevChangeDate date = null
        , @prevActionType varchar(50) = null

update mytable
set ActionType = case when isnull(@prevChangeDate,'1900-01-01')<=ChangeDate then 'Change'
else 'Add'
end
, @prevPK = PK
, @prevEffDate = prevEffDate
, @prevChangeDate = prevChangeDate
, @prevActionType = prevActionType 

...这将更新每行的变量并进行比较并适当地为每一行设置ActionType;但是,案例陈述没有适当评估。

我是否按正确的顺序设置了分配?

这是在SQL Server 2008 R2上。

如果您需要进一步说明,请与我们联系。 谢谢! -Wesley

1 个答案:

答案 0 :(得分:0)

尝试这样的事情(没有经过全面测试,但应该让你知道去哪里):

CREATE TABLE #Test (pk int, changedate datetime, ActionType varchar(50))

INSERT INTO #Test
SELECT 1, NULL, NULL UNION ALL
SELECT 2, '2015-01-01', NULL UNION ALL
SELECT 4, '2015-02-01', NULL UNION ALL
SELECT 5, '2015-03-01', NULL UNION ALL
SELECT 6, '2015-04-01', NULL UNION ALL
SELECT 10, NULL, NULL UNION ALL
SELECT 11, '2015-01-01', NULL


;WITH tableData AS (
    SELECT pk, ChangeDate, ROW_NUMBER() OVER (ORDER BY pk) AS RowNum
    FROM #Test
)
UPDATE #Test SET
    ActionType = x.ActionType
FROM (
    SELECT T.pk, CASE WHEN isnull(TPrev.ChangeDate,'1900-01-01') <= T.ChangeDate THEN 'Change' ELSE 'Add' END AS ActionType
    FROM tableData T
    LEFT JOIN tableData TPrev ON TPrev.RowNum - 1 = T.RowNum
) X WHERE X.pk = #Test.pk

SELECT *
FROM #Test

它基本上使用ROW_NUMBER来确保顺序ID(如果跳过或过滤了一个)

然后,自我加入以获得以前的记录。

然后执行更新来更新字段。