更新字段时要进行的计算

时间:2015-02-09 19:44:50

标签: mysql sql-server

Origin     Dest      Date                              Amount    50% Due
92509      0021      2013-07-30 00:00:00.000           5.37       0.00
92509      0021      2013-07-30 00:00:00.000           5.37       0.00
92509      0021      2013-07-30 00:00:00.000           5.37       0.00
92509      0021      2013-07-31 00:00:00.000           5.37       2.69
92509      0021      2013-07-31 00:00:00.000           5.37       2.69
92509      0021      2013-07-31 00:00:00.000           5.37       2.69
92509      0021      2013-08-01 00:00:00.000           5.37       2.69
92509      0021      2013-08-01 00:00:00.000           5.37       2.69
42101      0029      2013-03-06 00:00:00.000           6.06       0.00
42101      0029      2013-03-06 00:00:00.000           6.06       0.00
42101      0029      2013-03-07 00:00:00.000           6.06       3.03
42101      0029      2013-03-07 00:00:00.000           6.06       3.03                        
42101      0030      2013-03-06 00:00:00.000           6.06       0.00   
42101      0030      2013-03-06 00:00:00.000           6.06       0.00   
42101      0030      2013-03-07 00:00:00.000           6.06       3.03   
42101      0030      2013-03-07 00:00:00.000           6.06       3.03   

所以我有一张类似于上面所示的表格。现在,50%到期字段为空。我需要用上面显示的值填充该字段。

50%到期字段应填充金额字段中存在的值的一半。但是,它应该在初始日期(2013-07-30 00:00:00.000)填满零,并且连续几天它应该填充金额字段中存在的一半。

我有很多这样的行需要更新。还有一些具有不同Origin和Destination的行。

我正在处理一些货运包裹。该数据描述了连续几天从同一来源发送到同一目的地的宗地。连续几天发送的包裹可能在初始日期本身一起发送。因此,我试图为连续几天从同一来源发送到同一目的地的那些包裹产生索赔。并且50%到期将是索赔!

我对SQL很新!这对我来说似乎很复杂。请帮忙。

1 个答案:

答案 0 :(得分:0)

如果您想要更新前一天有条目的所有origin / dest组合,那么您可以这样做:

update t
set [50% due]=coalesce(cast(p.amount/2.0 as smallmoney),0.00)
from [table] t
left join [table] p
    on t.origin=p.origin and t.dest=p.dest 
    and dateadd(D,-1,cast(t.[date] as date))=cast(p.[date] as date)

或在SQL 2012及更高版本中使用cte和LAG:

;with previous as
(
    select origin,dest,[date]
    ,LAG(cast([date] as date),1,cast([date] as date)) OVER (PARTITION BY origin,dest ORDER BY cast([date] as date)) as previous
    from (select distinct origin, dest, [date]
            from [table]) a
)
update t
set [50% Due]=case when dateadd(D,-1,cast(t.[date] as date))<>cte.previous then 0.00 else cast(t.[amount]/2.0 as smallmoney) end
from [table] t
join previous cte
    on cte.origin=t.origin and cte.dest=t.dest and cte.[date]=t.[date]

如果要根据origin / dest组合发生的最早日期更新所有记录,那么这将在SQL Server中起作用:

;with earliest as
(
    select origin,dest,min(cast([date] as date)) earliest
    from [table]
    group by origin,dest
)
update t
set [50% Due]=case when cast(t.[date] as date)=cte.earliest then 0.00 else cast(t.[amount]/2.0 as smallmoney) end
from [table] t
join earliest cte
    on cte.origin=t.origin and cte.dest=t.dest

如果您只想根据表格中的最早日期更新所有记录,并且您不关心orgin / dest组合,那么您不需要使用cte对最早的日期进行分组,您可以在更新中进行比较。

UPDATE t
set [50% Due]=case when cast(t.[date] as date)=(select min(cast(t.date as date))) then 0.00 else cast(t.[amount]/2.0 as smallmoney) end