• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 420
  • Last Modified:

Looking for a way to reference two rows in the same table in SQL statement and update data from one with the other

I have a table created as such:
CREATE TABLE `full_daily_data` (
  `Symbol` varchar(9) NOT NULL,
  `Trade_Date` date NOT NULL DEFAULT '0000-00-00',
  `Day_Open` float DEFAULT NULL,
  `Day_High` float DEFAULT NULL,
  `Day_Low` float DEFAULT NULL,
  `Day_Close` float DEFAULT NULL,
  `Prior_Open` float DEFAULT NULL,
  `Prior_High` float DEFAULT NULL,
  `Prior_Low` float DEFAULT NULL,
  `Prior_Close` float DEFAULT NULL,
  PRIMARY KEY (`Symbol`,`Trade_Date`),
  KEY `TradeDate` (`Trade_Date`) ); 

Open in new window


I have it populated with data in these fields:
  `Symbol`
  `Trade_Date`
  `Day_Open`
  `Day_High`
  `Day_Low`
  `Day_Close`

What I want to do is have a SQL statement which will do one of two things:
1. With the data in symbol, then date order, take the data for the open, high, low and close from the row for one day and put them in the corresponding 'prior_' fields for the row in the corresponding following day (assuming that the symbol is the same).  Sounds like an aggresive if not impossible thing to do in just SQL... is it?
or, if not possible, then:
2. have a SQL statement that simply gets the data from one day for a symbol, and puts the open, high, low, close into the corresponding "Prior_" values in the row for the next day.

Any suggestions on this?
0
cashonly
Asked:
cashonly
2 Solutions
 
DcpKingCommented:
No - not impossible at all

update fdd1
    set fdd1.Prior_Open = fdd2.Day_Open,
          fdd1.Prior_Close = fdd2.Day_Close
    from full_daily_data fdd1
    inner join full_daily_data fdd2
    on fdd2.Trade_Date = DATE_SUB(fdd1.Trade_Date, INTERVAL 1 DAY)

Open in new window


(I just did 2 of the five)

The idea is that you have two aliases to the same table, and you link one to the other one day out-of-step.

hth

Mike
0
 
awking00Commented:
I think you may need to consider the case when the trade date is Monday and the previous trade date was Friday. This can get further complicated when holiday's are introduced. If you have a late enough version, perhaps the lead/lag functions might be of help.
0
 
cashonlyAuthor Commented:
DCPKing, nice!

awking00, good point.

Need some kind of function to integrate in the holiday/weekend (also 9/11 type closures) that would replace the "1" in the INTERVAL 1 DAY clause

I'm going to award points on what you've donw so far and carry this discussion on to this question:
http://www.experts-exchange.com/Programming/Languages/SQL_Syntax/Q_28144164.html
0
The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

 
DcpKingCommented:
To vary the interval ("interval 2 day", for example) :


@OffsetNumber = 2

PREPARE stmt FROM 

'   update fdd1
       set fdd1.Prior_Open = fdd2.Day_Open,
             fdd1.Prior_Close = fdd2.Day_Close
       from full_daily_data fdd1
       inner join full_daily_data fdd2
       on fdd2.Trade_Date = DATE_SUB(fdd1.Trade_Date, INTERVAL ? DAY);   '

EXECUTE stmt USING @OffsetNumber

Open in new window


Again, please excuse any syntax errors -  I don't have a MySQL machine with me!

hth

Mike
0
 
PortletPaulfreelancerCommented:
there is a small issue in the join above, it must use fdd1.symbol = fdd2.symbol in addition to the date. The following works as a select, but the MySQL update syntax is a little different:
select
  fdd1.Symbol
, fdd1.Trade_Date
, fdd1.Day_Open
, fdd1.Day_High
, fdd1.Day_Low
, fdd1.Day_Close
, fdd2.Day_Open  pdo
, fdd2.Day_High  pdh
, fdd2.Day_Low   pdl
, fdd2.Day_Close pdc
from full_daily_data fdd1
inner join full_daily_data fdd2
on fdd1.symbol = fdd2.symbol
and fdd2.Trade_Date = DATE_SUB(fdd1.Trade_Date, INTERVAL 1 DAY)
;

## syntax for the update is like this:
update full_daily_data fdd1
inner join full_daily_data fdd2
on fdd1.symbol = fdd2.symbol
and fdd2.Trade_Date = DATE_SUB(fdd1.Trade_Date, INTERVAL 1 DAY)
set
  fdd1.Prior_Open  = fdd2.Day_Open
, fdd1.Prior_High  = fdd2.Day_High
, fdd1.Prior_Low   = fdd2.Day_Low
, fdd1.Prior_Close = fdd2.Day_Close
;

Open in new window

see: http://sqlfiddle.com/#!9/cc5f0/1
0
 
DcpKingCommented:
Thanks, PortletPaul, for spotting the mistake!  As soon as you pointed it out it became glaringly obvious !
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

Tackle projects and never again get stuck behind a technical roadblock.
Join Now