2013-06-21 58 views
0

我试图使标题尽可能的通用,但我确实有这个想法很具体的例子:如何更新相关行基于最小/最大值的行

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

欲填充以下逻辑EndDates:

用于行X的结束日期应该对应于最小具有相同的ID的行的X和具有比所述起始日期StartDates更大所有其它行的StartDates的的行X.

到目前为止,我提出的唯一解决方案涉及逐行循环和逐行执行更新语句,这些语句的性能很糟糕。我在这一点上有点失落。我遍历类似于以下,使用保持着我感兴趣的(与空结束日期的那些)的行的临时表:

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 [email protected] 
and BaseTable.StartDate > TempTable.StartDate 
group by TempTable) Minimum 
where BaseTable.Id=Minimum.RowId 
+0

你想出了什么解决方案? –

+0

稍微过长,这是一个循环加这样的语句:UPDATE BaseTable SET effectiveEndDate为= Minimum.Date 从 (选择分钟(BaseTable.StartDate)日期,不是Temptable为RowId的 FROM不是Temptable INNER JOIN BaseTable 上BaseTable .ID = TempTable.ID 其中[email protected] 和BaseTable.StartDate> TempTable.StartDate group by TempTable)最小值 其中BaseTable.Id = Minimum.RowId; –

+0

对不起格式化,但我不知道如何格式化这些评论。我应该指出TempTable保存关于这种情况下要更改的行的信息(具有空结束日期的行) –

回答

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,但你必须编写一些代码以模拟SQL Server 2012中新增的LAG函数。

+0

是的,我的错。我应该指定SQL Server。我将不得不看看这个,并看看如何比较其他选项的性能。谢谢。 –

+0

啊。这实际上并不适合我的目的,因为如果下一个StartDate不是严格大于EndDate,我不想更新EndDate。其他人可能会觉得这很有用。 –

+0

我认为我的查询完成了你所描述的内容,但我可能是错的。行由startdate按降序排列。 LAG将选择前一行,根据该顺序将是所有开始日期的最小开始日期,高于当前开始日期。如果没有前一行(没有更高的startdate),那么该值将保持为NULL。 – JodyT

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中,您可能需要更多级别的子查询。

+0

是的,我刚刚结束了这样的事情,我自己,它很好。我想在发布这个问题之前我应该​​先弄清楚一些事情,但是当时我感觉有点不深。 –