Solved

Update Previous Price for datatable

Posted on 2013-11-06
6
283 Views
Last Modified: 2013-11-13
I have a table
ModelID,
Code,
BusDate,
Price
PrevPrice


I need to update the PrevPrice by getting the Price value for a given ModelID, Code from the previous BusDate.

The tables primary key is ModelID, Code, BusDate

Example
ModelID, Code, BusDate ,     Price,   PrevPrice
1 ,            'ABX', 10/18/2013 ,  7.00  ,   0
1 ,            'ABX', 10/18/2013 ,  9.00  ,   0
1 ,            'ABX', 10/21/2013 ,  10.00 ,   0
1 ,            'ABX', 10/22/2013 ,  8.00  ,   0

In the above example I would the data after the update statement to be
1 ,            'ABX', 10/18/2013 ,  7.00  ,   0
1 ,            'ABX', 10/18/2013 ,  9.00  ,   7.00
1 ,            'ABX', 10/21/2013 ,  10.00 ,   9.00
1 ,            'ABX', 10/22/2013 ,  8.00  ,   10.00
0
Comment
Question by:countrymeister
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
6 Comments
 
LVL 32

Expert Comment

by:awking00
ID: 39628104
Can we assume a time value is present for the busdate? Otherwise, how would you distinguish
1 ,            'ABX', 10/18/2013 ,  7.00  ,   0
1 ,            'ABX', 10/18/2013 ,  9.00  ,   7.00
from
1 ,            'ABX', 10/18/2013 ,  9.00  ,   0
1 ,            'ABX', 10/18/2013 ,  7.00  ,   9.00
?
0
 
LVL 1

Author Comment

by:countrymeister
ID: 39628115
Sorry, my example should have had the following, since ModelID, Code and BusDate are the primary key

ModelID, Code, BusDate ,     Price,   PrevPrice
1 ,            'ABX', 10/17/2013 ,  7.00  ,   0
1 ,            'ABX', 10/18/2013 ,  9.00  ,   0
1 ,            'ABX', 10/21/2013 ,  10.00 ,   0
1 ,            'ABX', 10/22/2013 ,  8.00  ,   0

In the above example I would the data after the update statement to be
1 ,            'ABX', 10/17/2013 ,  7.00  ,   0
1 ,            'ABX', 10/18/2013 ,  9.00  ,   7.00
1 ,            'ABX', 10/21/2013 ,  10.00 ,   9.00
1 ,            'ABX', 10/22/2013 ,  8.00  ,   10.00
0
 
LVL 32

Expert Comment

by:awking00
ID: 39628239
SQL> select * from yourtable;
   MODELID COD BUSDATE        PRICE  PREVPRICE
---------- --- --------- ---------- ----------
         1 ABX 17-OCT-13          7          0
         1 ABX 18-OCT-13          9          0
         1 ABX 21-OCT-13         10          0
         1 ABX 22-OCT-13          8          0

SQL> merge into yourtable y
  2  using
  3  (select modelid, code, busdate, price,
  4   lag(price) over (partition by modelid, code order by busdate) prevprice
  5   from yourtable) x
  6  on (y.modelid = x.modelid and y.code = x.code and y.busdate = x.busdate)
  7  when matched then
  8  update set y.prevprice = nvl(x.prevprice,0);

4 rows merged.
SQL> select * from yourtable;
   MODELID COD BUSDATE        PRICE  PREVPRICE
---------- --- --------- ---------- ----------
         1 ABX 17-OCT-13          7          0
         1 ABX 18-OCT-13          9          7
         1 ABX 21-OCT-13         10          9
         1 ABX 22-OCT-13          8         10
0
Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

 
LVL 1

Author Comment

by:countrymeister
ID: 39628331
I cannot use lag as it is a 2012 function. I am using sql 2008
0
 
LVL 32

Accepted Solution

by:
awking00 earned 400 total points
ID: 39628447
Try this -
merge into yourtable a
using
(select x.modelid, x.code, x.busdate, x.price, nvl(y.price,0) as prevprice from
 (select modelid, code, busdate, price,
  row_number() over (partition by modelid, code order by busdate) rn
  from yourtable) x left join
 (select modelid, code, busdate, price,
  row_number() over (partition by modelid, code order by busdate) rn
  from yourtable) y
 on y.rn = x.rn - 1) z
on (a.modelid = z.modelid and a.code = z.code and a.busdate = z.busdate)
when matched then
update set prevprice = z.prevprice;
0
 
LVL 41

Assisted Solution

by:Sharath
Sharath earned 100 total points
ID: 39638028
You can try like this.
;with cte as (
  select *,row_number() over (partition by ModelID,Code order by BusDate) rn
    from test)
update c1
   set c1.PrevPrice = coalesce(c2.Price,0)
  from cte c1
  left join cte c2 on c1.rn = c2.rn + 1

Open in new window


check this. http://sqlfiddle.com/#!3/785590/13
0

Featured Post

Ransomware-A Revenue Bonanza for Service Providers

Ransomware – malware that gets on your customers’ computers, encrypts their data, and extorts a hefty ransom for the decryption keys – is a surging new threat.  The purpose of this eBook is to educate the reader about ransomware attacks.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I'm trying, I really am. But I've seen so many wrong approaches involving date(time) boundaries I despair about my inability to explain it. I've seen quite a few recently that define a non-leap year as 364 days, or 366 days and the list goes on. …
In this article we will get to know that how can we recover deleted data if it happens accidently. We really can recover deleted rows if we know the time when data is deleted by using the transaction log.
Using examples as well as descriptions, and references to Books Online, show the documentation available for datatypes, explain the available data types and show how data can be passed into and out of variables.
Viewers will learn how to use the SELECT statement in SQL and will be exposed to the many uses the SELECT statement has.

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question