2015-02-09 103 views
-1
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年7月30日00:00:00:00)之前,它應該填寫零,並且在連續的日期內它應該填寫「金額」字段中的一半。

我有很多這樣的行需要更新。還有一些行具有不同的來源和目的地。

我正在處理一些貨運包裹。數據描述連續幾天從同一來源發送到同一目的地的地塊。連續幾天發送的包裹本身可能已經在初始日期一起發送。因此,我正試圖爲連續幾天從同一來源發送到相同目的地的那些包裹生成索賠。而50%的到期將是索賠!

我對SQL相當陌生!這對我來說似乎很複雜。請幫忙。

+0

您可能必須在3個查詢中執行此操作。一個'選擇'來獲取該「第一」日期的值,然後2'更新':一個用於將日期匹配的字段清零,另一個用於執行50%的計算。 – 2015-02-09 19:46:53

+0

謝謝我正在嘗試一些你所說的話。但我真的很感激查詢! – Maash 2015-02-09 19:57:51

+1

我很難搞清楚你想做什麼。爲什麼你的桌子上有這麼多重複的東西?您是否希望將第一個50%添加到原始日期之後的第一個日期,將第二個50%添加到下一個日期?或者在第一次約會之後它總是50%?您的數據看起來像是嚴重需要規範化。 – 2015-02-09 20:08:25

回答

0

如果要更新對前一天的條目都起源/目標組合,那麼你可以這樣做:

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) 

或使用CTE和LAG在SQL 2012和更高版本:

;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] 

如果要更新基於最早的一天,發生了原點/目標組合的所有記錄,那麼這將在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 
+0

非常感謝Ben Kean!有效!! – Maash 2015-02-10 16:33:58

+0

嗨Ben Kean ..您的查詢幫助我填寫了需要填寫的幾列,但未能爲相同日期的不同Ship Origin和Dest組合做到這一點。如果你看看我發佈的問題中的最後8條數據行,你可以理解我想說的話。根據您的查詢,最後4行的50%到期字段中的值將被填充爲3.03。但是我需要按照上面的問題來填充它們。請幫助。這將非常感激。萬分感謝! – Maash 2015-02-10 22:33:35

+0

@Maash如果最後4行被填充爲3.03,那麼在這些日期之前必須有該起始/目的地組合的實例。嘗試添加'order by t.origin,t.dest,t.date',你會明白我的意思。我已經添加了一個解決方案,不會按來源和目標分組來確定最短日期。 – 2015-02-11 19:58:16