sql - 替换 SQL Server 2005 游标

标签 sql sql-server-2005 cursor

这是简化的游标:

SET IMPLICIT_TRANSACTIONS ON

SET @curTemp = CURSOR FAST_FORWARD
FOR
    SELECT gpno, ssn FROM EligCov Group BY gpno, ssn
OPEN @curTemp

-- loop through cursor and build output report table
FETCH NEXT FROM @curTemp INTO @gpno, @ssn
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @trnCnt = @trnCnt + 1

    -- get the max CovEndDate for this group/ssn combo
    SELECT @MaxCovEndDate=MAX(CovEndDate) FROM Payroll WHERE GroupNo=@gpno AND SSN=@ssn
    UPDATE EligCov SET CovEndDate = @MaxCovEndDate WHERE gpno=@gpno AND ssn=@ssn

    -- check transaction counts and commit if needed
    IF @trnCnt % 2000 = 0
    BEGIN
        IF @@TRANCOUNT > 0
        BEGIN
            COMMIT
        END
    END
    FETCH NEXT FROM @curTemp INTO @gpno, @ssn
END
CLOSE @curTemp
DEALLOCATE @curTemp 

SET IMPLICIT_TRANSACTIONS OFF

基本上表EligCov有一个不同的 groupNo/SSN组合。表 Payroll会有很多groupno/ssn组合。 Payroll 中的每一行表有一个 CovEndDate包含日期的列。

我只需要选择 max(CovEndDate)对于某个gpno/ssn来自 Payroll 的组合(这可能来自一行或数百行)并更新 CovEndDateEligCov表格(对于特定的 groupno/ssn 组合总是一行)。

payroll表有 10,000,000 多行和 EligCov表有 ~200,000 行。有没有办法将其更改为不使用光标?

重申一下,对于每个 group/ssnEligCov查看Payroll中的所有记录与相同group/ssn并捕获 max(CovEndDate)并更新 CovEndDateEligCov表。

谢谢。

最佳答案

当然 - 非常简单 - 使用 CTE(公用表表达式)按“分组”集对数据进行分区。

;WITH DataToUpdate AS
(
    SELECT  
        GroupNo, SSN, CovEndDate AS 'MaxCovEndDate',
        ROW_NUMBER() OVER(PARTITION BY GroupNo,SSN ORDER BY CovEndDate DESC) AS 'RowNum'
    FROM dbo.Payroll 
UPDATE 
)
UPDATE dbo.EligCov 
SET CovEndDate = d.MaxCovEndDate 
FROM DataToUpdate d
WHERE gpno = d.GroupNo 
  AND ssn = d.SSN 
  AND d.RowNum = 1   -- select the latest date - the one with RowNum = 1

CTE 按 GroupNo,SSN 对您的数据进行分区 - 因此每组 GroupNo,SSN 都会分发新的 ROW_NUMBER(),开始在 1。由于行按 CovEndDate DESC 排序,最新/最近的 CovEndDate 得到 RowNum = 1

然后根据该 CTE,您更新 EligCov 表,仅获取每组 GroupNo,SSN

的最新条目

关于sql - 替换 SQL Server 2005 游标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7152443/

相关文章:

sql - 为什么 postgresql 不使用我的 group by 聚合索引?

sql-server-2005 - 更新SQL Server中的自动增量列

SQL 查询而不是游标

sql - 如何在SQL中选择没有时间的日期

javascript - 将值插入光标所在的最后一个文本区域

android - 如何使用一个游标从数据库中检索 2 列数据

sql - 查询元素依赖于另一个

mysql - 如何从最后一条记录 = x 中选择?

sql - 如何将一个表中的数据追加到另一个表中,其中一列是带有 sql 的 xml?

sql-server - SQL Server聚集索引: (Physical) Data Page Order