如何根据相关行中的最小/最大值更新行

时间:2013-06-21 18:45:33

标签: sql performance

我试图让标题尽可能通用,但我确实有一个非常具体的例子:

我有一个表格,其中我的行有一个StartDate和一个EndDate。每行也将与ID相关联。为简单起见,我们假设每个EndDate当前都是NULL。

我想用以下逻辑填充EndDates:

行X的EndDate应该对应于与行X具有相同ID并且StartDates大于行X的StartDate的所有其他行的StartDates的最小值。

到目前为止,我提出的唯一解决方案是逐行循环并逐行执行更新语句,这会产生糟糕的性能。我在这一点上有点失落。我循环使用一个临时表来保存我感兴趣的行(具有空结束日期的行):

UPDATE BaseTable 
SET EffectiveEndDate=Minimum.Date 
from (
select min(BaseTable.StartDate) as date, TempTable as RowId 

FROM TempTable INNER JOIN BaseTable 
on BaseTable.ID=TempTable.ID 

where TempTable.row=@row 
and BaseTable.StartDate > TempTable.StartDate 
group by TempTable) Minimum 
where BaseTable.Id=Minimum.RowId

2 个答案:

答案 0 :(得分:0)

如果您指定RDBMS会有所帮助,但使用SQL Server 2012,您可以使用分析函数LEADLAG。根据您的描述,我认为以下内容可行:

SELECT 
    id, 
    startdate,  
    LAG(startdate) OVER (PARTITION BY id ORDER BY startdate DESC)
FROM Table
ORDER BY id, startdate DESC;

SQL Fiddle

修改

旧版本的SQL Server应该可以实现相同的功能,但您必须编写一些代码来模拟LAG函数,因为它是SQL Server 2012中的新功能。

答案 1 :(得分:0)

以下是如何执行此操作的示例:

update t
    set EndDate = (select min(t2.StartDate)
                   from t t2
                   where t2.id = t.id and 
                         t2.StartDate > t.StartDate
                  )
    where EndDate is null;

这是标准SQL,因此它应该在大多数数据库中运行。在MySQL中,您可能需要额外级别的子查询。